资讯专栏INFORMATION COLUMN

raise 与 raise ... from 的区别

sPeng / 3172人阅读

摘要:处理异常时发生了新的异常,在不使用时更倾向于新异常与正在处理的异常没有关联。而则是能指出新异常是因旧异常直接引起的。这样的异常之间的关联有助于后续对异常的分析和排查。若要忽略上下文,则可以通过来禁止自动显示异常上下文。

起步

Python 的 raiseraise from 之间的区别是什么?

try:
    print(1 / 0)
except Exception as exc:
    raise RuntimeError("Something bad happened")

输出:

Traceback (most recent call last):
  File "test4.py", line 2, in 
    print(1 / 0)
ZeroDivisionError: division by zero

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test4.py", line 4, in 
    raise RuntimeError("Something bad happened")
RuntimeError: Something bad happened

raise from

try:
    print(1 / 0)
except Exception as exc:
    raise RuntimeError("Something bad happened") from exc

输出:

Traceback (most recent call last):
  File "test4.py", line 2, in 
    print(1 / 0)
ZeroDivisionError: division by zero

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

Traceback (most recent call last):
  File "test4.py", line 4, in 
    raise RuntimeError("Something bad happened") from exc
RuntimeError: Something bad happened
分析

不同之处在于,from 会为异常对象设置 __cause__ 属性表明异常的是由谁直接引起的。

处理异常时发生了新的异常,在不使用 from 时更倾向于新异常与正在处理的异常没有关联。而 from 则是能指出新异常是因旧异常直接引起的。这样的异常之间的关联有助于后续对异常的分析和排查。from 语法会有个限制,就是第二个表达式必须是另一个异常类或实例。

如果在异常处理程序或 finally 块中引发异常,默认情况下,异常机制会隐式工作会将先前的异常附加为新异常的 __context__ 属性。

当然,也可以通过 with_traceback() 方法为异常设置上下文 __context__ 属性,这也能在 traceback 更好的显示异常信息。

raise Exception("foo occurred").with_traceback(tracebackobj)
禁止异常关联

from 还有个特别的用法:raise ... from None ,它通过设置 __suppress_context__ 属性指定来明确禁止异常关联:

try:
    print(1 / 0)
except Exception as exc:
    raise RuntimeError("Something bad happened") from None

输出:

Traceback (most recent call last):
  File "test4.py", line 4, in 
    raise RuntimeError("Something bad happened") from None
RuntimeError: Something bad happened
总结

在异常处理程序或 finally 块中引发异常,Python 会为异常设置上下文,可以手动通过 with_traceback() 设置其上下文,或者通过 from 来指定异常因谁引起的。这些手段都是为了得到更友好的异常回溯信息,打印清晰的异常上下文。若要忽略上下文,则可以通过 raise ... from None 来禁止自动显示异常上下文。

参考

https://docs.python.org/3/ref...

https://docs.python.org/3/lib...

PEP 3109 -- Raising Exceptions in Python 3000

PEP 3134 -- Exception Chaining and Embedded Tracebacks

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42804.html

相关文章

  • Python2 和 Python3 区别及兼容技巧

    摘要:前言最近之父龟爷终于在官方邮件组落实了的终焉之日。于之后的年月日发布,计划作为的最后一个版本。统一使用作为缩进,如果和同时存在,就会触发异常兼容技巧统一使用作为缩进。兼容技巧统一使用内置函数。统一输出函数中的即是关键字又是内置函数。 前言 最近 Python 之父 Guido van Rossum(龟爷)终于在 Python 官方邮件组落实了 Python 2.7 的终焉之日(EOL)...

    lmxdawn 评论0 收藏0
  • 总结:Python中异常处理

    摘要:尽量使用内置的异常处理语句来替换语句,比如语句,方法。以上是最简单的重新抛出异常的做法,也是推荐的做法。除了包含所有的外还包含了,和三个异常。避免在语句块中干一些没意义的事情,捕获异常也是需要成本的。 异常处理在任何一门编程语言里都是值得关注的一个话题,良好的异常处理可以让你的程序更加健壮,清晰的错误信息更能帮助你快速修复问题。在Python中,和不部分高级语言一样,使用了try/ex...

    douzifly 评论0 收藏0
  • python基础教程:错误处理和异常处理(二)

    摘要:语句就是帮助我们抛出知道异常的,比如的使用很简单,它的语法如下如果它后面不带表达式参数,它会重新引发当前作用域内最后一个激活的异常。,用于异常的串联。自定义的异常类的名称通常以错误结尾,类似与内置标准异常的命名。 前面我们讲到的Python编程过程中,在可能出现异常的地方使用尝试语句,来正确的处理一些异常,可以保证程序不中断继续运行。 showImg(https://segmentfa...

    wujl596 评论0 收藏0
  • 捕获异常然后再抛出另一个异常正确姿势

    摘要:下面我们来看一下效果下次需要捕获一个异常然后再抛出另一个异常的时候大家可以试试本文的方法。 一般实现捕获异常然后再抛出另一个异常的方法类似下面这样: def div(): 2 / 0 try: div() except ZeroDivisionError as e: raise ValueError(e) 不知道大家有没有注意到这样抛出异常的方式有一个很严重的...

    RebeccaZhong 评论0 收藏0
  • 奇技淫巧第二期

    摘要:因为产生的顺序是先比较第一位,再比较第二位,并且没有很好的解决办法。这种语法的限制是,需要保证异常从属与异常。两个异常都将显示。 这个系利的初衷是回顾琐碎知识点,但...

    Rocture 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<