在 python 3 中禁用异常链接
Posted
技术标签:
【中文标题】在 python 3 中禁用异常链接【英文标题】:Disable exception chaining in python 3 【发布时间】:2016-02-21 22:45:14 【问题描述】: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))
但我相信有更好的解决方案。
【问题讨论】:
【参考方案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
【讨论】:
以上是关于在 python 3 中禁用异常链接的主要内容,如果未能解决你的问题,请参考以下文章