Python quot;raise fromquot; usage(Python“从提高用法)
问题描述
Python中的raise和
raise from有什么区别?
尝试:引发 ValueError例外为 e:引发索引错误
产生的结果
Traceback(最近一次调用最后一次):<module> 中的文件tmp.py"第 2 行引发 ValueError值错误在处理上述异常的过程中,又出现了一个异常:回溯(最近一次通话最后):<module> 中的文件tmp.py"第 4 行引发索引错误索引错误
和
尝试:引发 ValueError例外为 e:从 e 引发 IndexError
产生的结果
Traceback(最近一次调用最后一次):<module> 中的文件tmp.py"第 2 行引发 ValueError值错误上述异常是以下异常的直接原因:回溯(最近一次通话最后):<module> 中的文件tmp.py"第 4 行从 e 引发 IndexError索引错误
解决方案不同的是,当你使用
from
时,__cause__
属性已设置并且消息指出异常直接由引起.如果省略from
则不会设置__cause__
,但也可以设置__context__
属性,并且然后,回溯将上下文显示为在处理其他发生的事情期间.如果您在异常处理程序中使用
raise
,则会设置__context__
;如果您在其他任何地方使用raise
也没有设置__context__
.如果设置了
__cause__
,则异常也会设置__suppress_context__ = True
标志;当__suppress_context__
设置为True
时,打印回溯时会忽略__context__
.当您从不想要显示上下文的异常处理程序引发时(不希望在处理另一个异常发生期间消息),然后使用
raise ... from None
将__suppress_context__
设置为True
.换句话说,Python 为异常设置了一个 context,这样您就可以自省引发异常的位置,让您查看是否有另一个异常被它替换.您还可以将 cause 添加到异常中,使回溯显式地显示另一个异常(使用不同的措辞),并忽略上下文(但在调试时仍然可以自省).使用
raise ... from None
可以抑制正在打印的上下文.请参阅
<块引用>raise
语句文档:<预><代码>>>>尝试:...打印(1/0)...除了例外作为exc:...从 exc 中引发 RuntimeError(发生了一些糟糕的事情")...回溯(最近一次通话最后):文件<stdin>",第 2 行,在 <module>ZeroDivisionError:整数除法或模数为零上述异常是以下异常的直接原因:回溯(最近一次通话最后):文件<stdin>",第 4 行,在 <module>RuntimeError:发生了一些不好的事情
from
子句用于异常链接:如果给定,第二个 expression 必须是另一个异常类或实例,然后将附加到引发的异常__cause__
属性(可写).如果未处理引发的异常,则将打印两个异常:如果在异常处理程序或
<预><代码>>>>尝试:...打印(1/0)... 除了:... raise RuntimeError(发生了一些不好的事情")...回溯(最近一次通话最后):文件<stdin>",第 2 行,在 <module>ZeroDivisionError:整数除法或模数为零在处理上述异常的过程中,又出现了一个异常:回溯(最近一次通话最后):文件<stdin>",第 4 行,在 <module>RuntimeError:发生了一些不好的事情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“从"提高用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!