小编典典

在python 3中禁用异常链接

python

python3中引入了一个新功能-异常链接。由于某些原因,我需要为代码中的某些异常禁用它。

这是示例代码:

try:
    print(10/0)
except ZeroDivisionError as e:
    sys.exc_info()
    raise AssertionError(str(e))

我所看到的:

Traceback (most recent call last):
  File "draft.py", line 19, in main
    print(10/0)
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "draft.py", line 26, in <module>
    main()
  File "draft.py", line 22, in main
    raise AssertionError(str(e))
AssertionError: division by zero

我想看的是:

Traceback (most recent call last):
  File "draft.py", line 26, in <module>
    main()
  File "draft.py", line 22, in main
    raise AssertionError(str(e))
AssertionError: division by zero

我尝试使用sys.exc_clear(),但是此方法也已从python 3中删除。我可以使用可行的解决方法

exc = None
try:
    print(10/0)
except ZeroDivisionError as e:
    exc = e
if exc:
    raise AssertionError(str(exc))

但我相信有更好的解决方案。


阅读 140

收藏
2021-01-16

共1个答案

小编典典

简单答案

try:
    print(10/0)
except ZeroDivisionError as e:
    raise AssertionError(str(e)) from None

但是,您实际上可能想要:

try:
    print(10/0)
except ZeroDivisionError as e:
    raise AssertionError(str(e)) from e

说明

__cause__

__context__当没有显式原因异常集时,隐式异常链就会发生。

显式异常链接可以正常工作,__cause__因此,如果您将__cause__异常设置为自身,则应停止链接。如果__cause__设置为,Python将禁止隐式消息。

try:
    print(10/0)
except ZeroDivisionError as e:
    exc = AssertionError(str(e))
    exc.__cause__ = exc
    raise exc

从…提高

我们可以使用“ raise from”来做同样的事情:

try:
    print(10/0)
except ZeroDivisionError as e:
    exc = AssertionError(str(e))
    raise exc from exc

没有 __cause__

设置__cause__None实际上会执行相同的操作:

try:
    print(10/0)
except ZeroDivisionError as e:
    exc = AssertionError(str(e))
    exc.__cause__ = None
    raise exc

从无提高

所以这给我们带来了 最优雅的方式 来做到这一点这是 提高来自None

try:
    print(10/0)
except ZeroDivisionError as e:
    raise AssertionError(str(e)) from None

但我认为您通常希望从原因异常中显式引发异常,以便保留回溯:

try:
    print(10/0)
except ZeroDivisionError as e:
    raise AssertionError(str(e)) from e

这将给我们一个稍微不同的消息,指出第一个异常是第二个异常的直接原因:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
AssertionError: division by zero
2021-01-16