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

时间:2014-09-15 13:36:28

标签: python exception python-3.x exception-handling 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,但两者都显示在控制台中。

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

1 个答案:

答案 0 :(得分:3)

控制台在此处显示上下文;当从异常处理程序引发异常时,Python将活动异常作为__context__属性附加,如果未处理新异常,Python稍后会显示该上下文。如果您不希望显示上下文,则需要提供原因;您可以使用raise ... from None提供空的原因:

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

引用raise statement documentation

  

from子句用于异常链接:如果给定,则第二个表达式必须是另一个异常类或实例,然后将其作为__cause__属性附加到引发的异常(这是可写)。如果未处理引发的异常,则将打印两个例外[...]

     

如果在异常处理程序中引发异常,则类似的机制会隐式工作:然后将先前的异常附加为新异常的__context__属性[...]

来自Exceptions documentation

  

当引发(或重新引发)except子句__context__中的异常时,会自动设置为捕获的最后一个异常;如果未处理新异常,则最终显示的回溯将包括原始异常和最终异常。

     

在引发新异常时(而不是使用裸raise重新引发当前正在处理的异常),可以使用from和{raise来明确隐含异常上下文。 {1}}:

raise new_exc from original_exc
     

以下表达式必须是例外或None。它将在引发的异常上设置为__cause__。设置__cause__也会隐式将__suppress_context__属性设置为True,以便使用raise new_exc from None有效地将旧异常替换为新异常以用于显示目的(例如转换KeyError }} AttributeError),同时在__context__中保留旧的异常,以便在调试时进行内省。

     

默认的回溯显示代码除了显示异常本身的回溯外,还会显示这些链接的异常。 __cause__中的显式链接异常在出现时始终显示。仅当__context__为无且__cause__为false时,才会显示__suppress_context__中的隐式链接异常。