python - 在 python 3 中禁用异常链接

标签 python python-3.x exception

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

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

最佳答案

简单回答

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 - 在 python 3 中禁用异常链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33809864/

相关文章:

python - TensorFlow dynamic_rnn 回归量 : ValueError dimension mismatch

python - 为什么 TensorFlow WHL 文件不包含所有必需的依赖项?

python - 使用存储在字典中的字符串调用类

regex - 限制scrapy抓取子域

.net - AppDomain.UnhandledException 事件如何工作?

java - 为什么我无法启动 JavaFX 程序?

python - 如何在 map 方法中预处理和标记 TensorFlow CsvDataset?

Python 3 + MySQL : Incorrect string value '\xF0\x9F\x85\x97\xF0\x9F...'

python - 如何在 Python 3.3 中更改 ttk.Treeview 列宽和粗细

.net - 如何从 SQL Server 找出_确切_错误