【问题标题】:How to access re-raised exception in Python 3?如何在 Python 3 中访问重新引发的异常?
【发布时间】:2016-10-08 16:32:29
【问题描述】:

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

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

【问题讨论】:

  • 顺便说一句:使用from 在执行raise Exception("blah") from None 时最有用,它告诉python 隐藏 TypeError 并使其无法访问。 默认情况下 TypeError 已经存储在新异常中(这就是为什么您在回溯中看到 During handling of the above exception blah 消息的原因)所以这样做 raise ... from err 几乎没用。

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


【解决方案1】:

它在引发异常的__cause__ 属性中。取自docs on the raise statement,它说关于raise ... from ...

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

因此,在您给定的场景中,repring __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",)

【讨论】:

    【解决方案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
    

    【讨论】:

    • 啊,整洁。不知道__context__
    猜你喜欢
    • 2021-10-04
    • 1970-01-01
    • 2016-03-18
    • 2011-09-12
    • 2021-11-24
    • 1970-01-01
    • 2018-12-14
    • 2011-09-10
    • 2018-12-11
    相关资源
    最近更新 更多