【问题标题】:Python: Exception raised even when caught in try/except clause [duplicate]Python:即使在 try/except 子句中捕获也会引发异常 [重复]
【发布时间】:2014-11-09 01:24:57
【问题描述】:

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

执行时:

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 exception python-3.x exception-handling try-catch


    【解决方案1】:

    控制台在这里显示上下文;当从异常处理程序引发异常时,Python 将活动异常附加为 __context__ 属性,如果未处理新异常,Python 稍后会显示该上下文。如果您不希望显示上下文,则需要提供 cause;您可以使用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 来重新引发当前正在处理的异常),隐式异常上下文可以通过使用fromraise 来补充一个显式原因:

    raise new_exc from original_exc
    

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

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

    【讨论】:

    • raise Exception from None 在 python shell 中给出了 SyntaxError。这是自然行为吗?
    • @SecerH.:这仅适用于 Python 3。如果您看到语法错误,则您正在使用 Python 2。
    猜你喜欢
    • 1970-01-01
    • 2020-10-17
    • 2023-03-31
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多