Python“从"提升用法 [英] Python "raise from" usage
问题描述
Python 中的 raise
和 raise from
有什么区别?
尝试:引发值错误除了作为 e 的例外:引发索引错误
产生的结果
回溯(最近一次调用最后一次):文件tmp.py",第 2 行,在 <module> 中引发值错误值错误在处理上述异常的过程中,又发生了一个异常:回溯(最近一次调用最后一次):文件tmp.py",第 4 行,在 <module> 中引发索引错误索引错误
和
尝试:引发值错误除了作为 e 的例外:从 e 引发 IndexError
产生的结果
回溯(最近一次调用最后一次):文件tmp.py",第 2 行,在 <module> 中引发值错误值错误上述异常是以下异常的直接原因:回溯(最近一次调用最后一次):文件tmp.py",第 4 行,在 <module> 中从 e 引发 IndexError索引错误
不同的是,当你使用 from
时,__cause__
属性已设置并且消息指出异常是直接由引起的.如果省略 from
则不会设置 __cause__
,但也可以设置 __context__
属性,并且然后回溯将上下文显示为在处理其他事情时.
设置 __context__
如果您在异常处理程序中使用了 raise
;如果你在其他任何地方使用了 raise
也没有设置 __context__
.
如果设置了 __cause__
,则异常也会设置 __suppress_context__ = True
标志;当 __suppress_context__
设置为 True
时,打印回溯时会忽略 __context__
.
当从您不想想要显示上下文的异常处理程序引发时(不希望在处理另一个异常时发生消息),然后使用 raise ... from None
将 __suppress_context__
设置为 True
.
换句话说,Python 为异常设置了上下文,这样您就可以内省异常发生的位置,让您查看是否有另一个异常被它替换.您还可以向异常添加原因,使回溯明确关于另一个异常(使用不同的措辞),并忽略上下文(但在调试时仍然可以自省).使用 raise ... from None
可以抑制正在打印的上下文.
请参阅raise
声明文档:
from
子句用于异常链接:如果给定,第二个表达式必须是另一个异常类或实例,然后将其附加到引发的异常作为__cause__
属性(可写).如果未处理引发的异常,则将打印两个异常:
如果在异常处理程序或 finally
子句中引发异常,则类似的机制会隐式工作:然后将先前的异常附加为新异常的 __context__
属性:
另请参阅内置异常文档有关附加到异常的上下文和原因信息的详细信息.
What's the difference between raise
and raise from
in Python?
try:
raise ValueError
except Exception as e:
raise IndexError
which yields
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError
IndexError
and
try:
raise ValueError
except Exception as e:
raise IndexError from e
which yields
Traceback (most recent call last):
File "tmp.py", line 2, in <module>
raise ValueError
ValueError
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "tmp.py", line 4, in <module>
raise IndexError from e
IndexError
The difference is that when you use from
, the __cause__
attribute is set and the message states that the exception was directly caused by. If you omit the from
then no __cause__
is set, but the __context__
attribute may be set as well, and the traceback then shows the context as during handling something else happened.
Setting the __context__
happens if you used raise
in an exception handler; if you used raise
anywhere else no __context__
is set either.
If a __cause__
is set, a __suppress_context__ = True
flag is also set on the exception; when __suppress_context__
is set to True
, the __context__
is ignored when printing a traceback.
When raising from a exception handler where you don't want to show the context (don't want a during handling another exception happened message), then use raise ... from None
to set __suppress_context__
to True
.
In other words, Python sets a context on exceptions so you can introspect where an exception was raised, letting you see if another exception was replaced by it. You can also add a cause to an exception, making the traceback explicit about the other exception (use different wording), and the context is ignored (but can still be introspected when debugging). Using raise ... from None
lets you suppress the context being printed.
See the raise
statement documenation:
The
from
clause is used for exception chaining: if given, the second expression must be another exception class or instance, which will then be attached to the raised exception as the__cause__
attribute (which is writable). If the raised exception is not handled, both exceptions will be printed:>>> try: ... print(1 / 0) ... except Exception as exc: ... raise RuntimeError("Something bad happened") from exc ... Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: int division or modulo by zero The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<stdin>", line 4, in <module> RuntimeError: Something bad happened
A similar mechanism works implicitly if an exception is raised inside an exception handler or a
finally
clause: the previous exception is then attached as the new exception’s__context__
attribute:>>> try: ... print(1 / 0) ... except: ... raise RuntimeError("Something bad happened") ... Traceback (most recent call last): File "<stdin>", line 2, in <module> ZeroDivisionError: int division or modulo by zero During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 4, in <module> RuntimeError: Something bad happened
Also see the Built-in Exceptions documentation for details on the context and cause information attached to exceptions.
这篇关于Python“从"提升用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!