Python 中 raise 和 raise/from 的区别 您所在的位置:网站首页 raise的用法和搭配 Python 中 raise 和 raise/from 的区别

Python 中 raise 和 raise/from 的区别

#Python 中 raise 和 raise/from 的区别| 来源: 网络整理| 查看: 265

Python 中 raise 和 raise/from 的使用方法

文章目录 Python 中 raise 和 raise/from 的使用方法0. 参考资料1. 代码比较2. 用法解释2.1 raise2.2 raise A from B 3. 总结

0. 参考资料 Python “raise from” usageThe raise statementBuilt-in Exceptions 1. 代码比较

今天在看《Effective Python》的时候第一次见到 raise A from B 的用法,所以在网上查了一下。 下面用代码比较一下 raise 和 raise/from 的区别。

raise.py # raise try: raise ValueError except Exception as e: raise IndexError """ Traceback (most recent call last): File "raise.py", line 3, in raise ValueError ValueError During handling of the above exception, another exception occurred: Traceback (most recent call last): File "raise.py", line 5, in raise IndexError IndexError """ raisefrom.py # raise/from try: raise ValueError except Exception as e: raise IndexError from e """ Traceback (most recent call last): File "raisefrom.py", line 3, in raise ValueError ValueError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "raisefrom.py", line 5, in raise IndexError from e IndexError """

上面的 raise 和 raise/from 都是放在 except 异常处理块中的。 可以观察到 raise 和 raise/from 最大的区别是异常提示信息不一样:

raise 是:During handling of the above exception, another exception occurred:。 即“在处理上面的异常时,发生了另外一个异常:”。而 raise/from 是:The above exception was the direct cause of the following exception:。 即“上面的异常是接下来的异常的直接原因:”。 2. 用法解释 2.1 raise

当在 except 块或者 finally 块中出现异常时(包括使用单独的 raise 重新抛出异常的情况),之前的异常会被附加到新异常的 __context__ 属性上。

except 块中的语句叫做异常处理器 exception handler,它们是处理异常的语句。

而在其他任何地方抛出异常,都不会设置 __context__ 属性。 这样打印出来的异常信息就会包含这么一句话:During handling of the above exception, another exception occurred:。

2.2 raise A from B

raise A from B 语句用于连锁 chain 异常。 from 后面的 B 可以是:

异常类异常实例None(Python 3.3 的新特性)

如果 B 是异常类或者异常实例,那么 B 会被设置为 A 的 __cause__ 属性,表明 A异常 是由 B异常 导致的。 这样打印出来的异常信息就会包含这样一句话:The above exception was the direct cause of the following exception:。 与此同时,在 Python 3.3 中 A异常 的 __suppress_context__ 属性会被设置为 True,这样就抑制了 A异常 的 __context__ 属性,即忽略 __context__ 属性。 于是 Python 就不会自动打印异常上下文 exception context,而是使用 __cause__ 属性来打印异常的引发者。

在 Python 3.3 中,B 还可以是 None:raise A异常 from None。 这样相当于把 __suppress_context__ 属性设置为 True,从而禁用了 __context__ 属性,Python 不会自动展示异常上下文。 比如下面这段代码,注意到只显示了 IndexError 一个异常信息: raisefromnone.py

# raise ... from None # 禁用异常上下文属性 try: raise ValueError except Exception as e: raise IndexError from None """ Traceback (most recent call last): File "raisefromnone.py", line 6, in raise IndexError from None IndexError """ 3. 总结

在 except 或者 finally 块中使用 raise 和 raise/from 语句需要注意:

raise 会设置后面异常的 __context__ 属性为前面的异常。 异常信息中会有 During handling of the above exception, another exception occurred:。raise A异常 from B异常 会把 A异常 的 __cause__ 属性设置为 B异常。 同时设置 __suppress_context__ 属性为 True,从而忽略 __context__ 属性,不打印异常上下文信息。 异常信息中会有 The above exception was the direct cause of the following exception:。raise A异常 from None 会设置 A异常 的 __suppress_context__ 属性为 True,这样会忽略它的 __context__ 属性,不会自动显示异常上下文信息。

完成于 2018.11.21



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有