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中删除。我可以使用可行的解决方法
sys.exc_clear()
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__当没有显式原因异常集时,隐式异常链就会发生。
__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__为None实际上会执行相同的操作:
None
try: print(10/0) except ZeroDivisionError as e: exc = AssertionError(str(e)) exc.__cause__ = None raise exc
所以这给我们带来了 最优雅的方式 来做到这一点这是 提高来自None:
但我认为您通常希望从原因异常中显式引发异常,以便保留回溯:
这将给我们一个稍微不同的消息,指出第一个异常是第二个异常的直接原因:
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