Python“从”提升“用法 [英] Python "raise from" usage
问题描述
$ b c
try:
pre>
raise ValueError
除了例外为e:
raise IndexError
它产生
追溯(最近最近的电话):
文件tmp.py,第2行,在< module>
raise ValueError
ValueError
在处理上述异常时发生了另一个异常:
追溯(最近的最后一次呼叫):
文件tmp.py,第4行,位于< module>
raise IndexError
IndexError
和
try:
raise ValueError
除了异常作为e:
从e
中提取IndexError $ b $ / code >其中
追溯(最近的通话最后):
文件tmp.py,第2行,位于< module>
raise ValueError
ValueError
以上异常是以下异常的直接原因:
追溯(最近的最后一次调用):
文件tmp.py,第4行,在< module>
从e
中提取IndexError IndexError
解决方案p>区别在于,当您使用中的
时,将设置
省略__ cause __
属性该消息指出异常是直接由引起的。如果您从,则不设置
__ cause __
,但__ context __
属性也可以设置,然后追踪在处理其他事情期间将上下文显示为。
如果您在异常处理程序中使用
raise
,则设置__上下文__
如果您在其他地方使用raise
,则不设置__ context __
。
如果设置了
__因为__
,则在异常上也设置__ suppress_context__ = True
标志。当__ suppress_context __
设置为True
时,__上下文__
被忽略当打印回溯时。
从异常处理程序提升时,您不要 要显示上下文(不想要<在处理另一个异常事件消息时),然后使用
raise ... from None
设置__ suppress_context __
到True
。
换句话说,Python在异常情况下设置一个上下文您可以内省异常的发生,让您看到是否被另一个异常所替代。您还可以向异常添加原因,使追溯显示关于其他异常(使用不同的措辞),并且上下文被忽略(但是在调试时仍可以进行内省化)。使用
raise ... from None
可以禁止打印上下文。
请参阅
raise
statement documenation :
来自子句的
子句用于异常链接:如果给定,则第二个表达式必须是另一个异常类或实例,然后将其作为
__ cause __
属性(可写)附加到引发的异常。如果未处理引发的异常,则将打印两个例外:>>>尝试:
...打印(1/0)
...除了异常作为exc:
...从exc
引发RuntimeError(Something bad happen)。
追溯(最近的最后一次呼叫):
文件< stdin>,第2行,< module>
ZeroDivisionError:int除数或模数为零
上述异常是以下异常的直接原因:
追溯(最近的最后一次调用):
文件< stdin>,第4行,< module>
RuntimeError:发生错误
类似的机制可以隐含地工作,如果在异常处理程序:>然后将以前的异常附加为新异常的
__上下文__
属性:>>>尝试:
... print(1/0)
...除了:
... raise RuntimeError(Something bad happen)
...
追溯(最近的呼叫最后):
文件< stdin>,第2行,< module>
ZeroDivisionError:int除数或模数为零
在处理上述异常时发生另一个异常:
追溯(最近的最后一次调用):
文件< stdin>,第4行在< module>
RuntimeError:发生错误
另请参阅<有关上下文和原因的详细信息,请参阅href =https://docs.python.org/3/library/exceptions.html#built-in-exceptions =noreferrer>内置例外文档
What's the difference between
raise
andraise 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 thefrom
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 usedraise
in an exception handler; if you usedraise
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 toTrue
, 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__
toTrue
.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: > 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屋!