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

时间:2016-10-08 16:32:30

标签: python python-3.x exception exception-handling

在Python 3中,有useful raise ... from ... feature重新引发异常。也就是说,如何从引发的异常中找到原始(/重新引发的)异常?这是一个(愚蠢的)例子,带有评论来证明我的意思 -

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)?

2 个答案:

答案 0 :(得分:3)

它位于引发异常的__cause__属性中。取自关于raise ... from ...的{​​{3}} {/ p>

  

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

因此,在您的给定方案中,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__))

将打印出来:

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

答案 1 :(得分:2)

每当从异常处理程序(except子句)引发异常时,原始异常将在新异常__context__中得到支持。

每当使用from语法引发异常时,from中指定的异常将保存在新异常的__cause__属性中。

在通常的使用案例中,这相当于包含原始例外的__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__)

以下是设置__context__的示例:

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

以及设置__cause__时的示例:

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