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