简体   繁体   English

如何访问Python 3中重新引发的异常?

[英]How to access re-raised exception in Python 3?

In Python 3, there's a useful raise ... from ... feature to re-raise an exception. 在Python 3中,有一个有用的raise ... from ...功能来重新引发异常。 That said, how do you find the original (/ re-raised) exception from the raised exception? 也就是说,如何从引发的异常中找到原始(/重新引发的)异常? Here's a (silly) example with comments to demonstrate what I mean-- 这是一个(带有愚蠢的)示例,上面有注释以说明我的意思-

def some_func():
    try:
      None() # TypeError: 'NoneType' object is not callable
    except as err:
      raise Exception("blah") from err

try:
    some_func()
except as err:
    # how can I access the original exception (TypeError)?

It's in the __cause__ attribute of the raised exception. 它在引发的异常的__cause__属性中。 Taken from the docs on the raise statement it says regarding raise ... from ... : 摘自对文档raise声明 ,它说关于raise ... from ...

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). from子句用于异常链接:如果给定,第二个表达式必须是另一个异常类或实例, 然后将其作为__cause__属性 (可写) 附加到引发的异常上 If the raised exception is not handled, both exceptions will be printed. 如果未处理引发的异常,则将打印两个异常。

So, in your given scenario, repr ing the __cause__ attribute: 因此,在给定的情况下, repr __cause__属性:

def some_func():
    try:
      None() # TypeError: 'NoneType' object is not callable
    except TypeError as err:
      raise Exception("blah") from err

try:
    some_func()
except Exception as er:
    print(repr(er.__cause__))

Will print out: 将打印出:

TypeError("'NoneType' object is not callable",)

Whenever an exception is raised from an exception handler (the except clause), the original exception will bestored in new exception's __context__ . 每当从异常处理程序( except子句)引发异常时,原始异常都会保留在新异常的__context__

Whenever an exception is raised using from syntax, the exception specified in from will be saved in the __cause__ attribute of the new exception. 每当使用from语法引发异常时,在from指定的异常将保存在新异常的__cause__属性中。

In the usual use case, that amounts to both __cause__ and __context__ containing the original exception: 在通常的用例中,这等于包含原始异常的__cause____context__

def f():
    try:
        raise Exception('first exception')
    except Exception as e:
        raise Exception('second exception') from e

try:
    f()
except Exception as e:
    print('This exception', e)
    print('Original exception', e.__context__)
    print('Also original exception', e.__cause__)

Here is also an example of when __context__ is set: 这也是设置__context__的示例:

try:
    raise Exception('first exception')
except Exception as e:
    raise Exception('second exception')

and an example of when __cause__ is set: 以及设置__cause__的时间的示例:

e = Exception('first exception')
raise Exception('second exception') from e

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM