Python:即使在 try/except 子句中捕获也会引发异常

标签 python python-3.x exception try-catch

<分区>

在我的代码中,我想在异常发生时捕获异常,将异常的一些信息打印到屏幕上,然后在完成后结束脚本。我尝试使用与以下代码等效的东西,但我不明白为什么我会得到回溯。

执行时:

try:
    1 / 0
except ZeroDivisionError:
    print("Exception: ZeroDivisionError")
    raise Exception

控制台读取:

Exception: ZeroDivisionError
Traceback (most recent call last):
  File "<pyshell#19>", line 2, in <module>
    1 / 0
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<pyshell#19>", line 5, in <module>
    raise Exception
Exception

我想如果我捕捉到 ZeroDivisionError,它就不会再被引发,唯一会显示的是我最后做的 raise Exception,但两者都显示在控制台中。

为什么它们都显示,我如何更改代码以便只显示第二个,或者是否有更好的方法来实现我想要的?

最佳答案

控制台在此处显示上下文;当异常处理程序引发异常时,Python 将事件异常附加为 __context__ 属性,如果未处理新异常,Python 会稍后显示该上下文。如果您不想显示上下文,则需要提供一个原因;你可以提供一个空的原因 with raise ... from None:

try:
    1 / 0
except ZeroDivisionError:
    print("Exception: ZeroDivisionError")
    raise Exception from None

引用raise statement documentation :

The from clause is used for exception chaining: if given, the second expression must be another exception class or instance, which will then be attached to the raised exception as the __cause__ attribute (which is writable). If the raised exception is not handled, both exceptions will be printed[...]

A similar mechanism works implicitly if an exception is raised inside an exception handler: the previous exception is then attached as the new exception’s __context__ attribute[...]

并且来自 Exceptions documentation :

When raising (or re-raising) an exception in an except clause __context__ is automatically set to the last exception caught; if the new exception is not handled the traceback that is eventually displayed will include the originating exception(s) and the final exception.

When raising a new exception (rather than using a bare raise to re-raise the exception currently being handled), the implicit exception context can be supplemented with an explicit cause by using from with raise:

raise new_exc from original_exc

The expression following from must be an exception or None. It will be set as __cause__ on the raised exception. Setting __cause__ also implicitly sets the __suppress_context__ attribute to True, so that using raise new_exc from None effectively replaces the old exception with the new one for display purposes (e.g. converting KeyError to AttributeError), while leaving the old exception available in __context__ for introspection when debugging.

The default traceback display code shows these chained exceptions in addition to the traceback for the exception itself. An explicitly chained exception in __cause__ is always shown when present. An implicitly chained exception in __context__ is shown only if __cause__ is None and __suppress_context__ is false.

关于Python:即使在 try/except 子句中捕获也会引发异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25849390/

相关文章:

python-3.x - Google 文本转语音 API 音调调整

python - 如何舍入python中的两位有效数字?

带有 expected = exception 的 Java 测试因断言错误而失败

c++ - what() 未打印的重新抛出异常的自定义错误消息

python - Kivy Action按钮无法通过python更新图标

java - aroundInvoke 和检查异常

python - 将 JSON 文件转换为 numpy 数组

python - 从日期到字符串的 Pyspark 类型转换问题

python - 从 ArgumentParser 获取允许参数的正确方法

python - 是否有任何适用于 Python 的自动更正/自动完成库?