Python“来自”用法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24752395/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python "raise from" usage
提问by darkfeline
What's the difference between raise
and raise from
in Python?
Python 中的raise
和 有什么区别raise from
?
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
采纳答案by Martijn Pieters
The difference is that when you use from
, the __cause__
attributeis 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__
attributemay be set as well, and the traceback then shows the context as during handling something else happened.
不同之处在于,当您使用 时from
,会设置该__cause__
属性,并且消息指出异常是由 直接引起的。如果省略from
则 no__cause__
被设置,但__context__
属性也可能被设置,然后回溯会显示上下文,就像在处理其他发生的事情时一样。
Setting the __context__
happens if you used raise
in an exception handler; if you used raise
anywhere else no __context__
is set either.
__context__
如果您raise
在异常处理程序中使用,则设置发生;如果您raise
在其他任何地方使用,也没有__context__
设置。
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.
如果__cause__
设置了 a __suppress_context__ = True
,则异常也会设置一个标志;当__suppress_context__
被设定为True
,在__context__
打印时,回溯忽略。
When raising from a exception handler where you don'twant to show the context (don't want a during handling another exception happenedmessage), then use raise ... from None
to set __suppress_context__
to True
.
从异常处理程序,你养的时候不希望显示上下文(不想处理另一个异常发生时,然后用消息)raise ... from None
来设置__suppress_context__
到True
。
In other words, Python sets a contexton 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 causeto 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.
换句话说,Python 为异常设置了一个上下文,以便您可以自省引发异常的位置,让您查看是否有另一个异常被它替换。您还可以为异常添加原因,使回溯明确关于另一个异常(使用不同的措辞),并且上下文被忽略(但在调试时仍然可以自省)。使用raise ... from None
可让您抑制正在打印的上下文。
See the raise
statement documenation:
请参阅raise
声明文档:
The
from
clause is used for exception chaining: if given, the second expressionmust 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
该
from
子句用于异常链接:如果给定,则第二个表达式必须是另一个异常类或实例,然后将其作为__cause__
属性(可写)附加到引发的异常。如果未处理引发的异常,则将打印两个异常:>>> 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
如果在异常处理程序或
finally
子句中引发异常,则类似的机制会隐式工作:然后将先前的异常附加为新异常的__context__
属性:>>> 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 documentationfor details on the context and cause information attached to exceptions.
另请参阅内置异常文档以获取有关上下文和附加到异常的原因信息的详细信息。