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
fromclause 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 happenedA similar mechanism works implicitly if an exception is raised inside an exception handler or a
finallyclause: 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“从"提高用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Python“从"提高用法
基础教程推荐
- PermissionError: pip 从 8.1.1 升级到 8.1.2 2022-01-01
- 修改列表中的数据帧不起作用 2022-01-01
- 包装空间模型 2022-01-01
- PANDA VALUE_COUNTS包含GROUP BY之前的所有值 2022-01-01
- 无法导入 Pytorch [WinError 126] 找不到指定的模块 2022-01-01
- 在同一图形上绘制Bokeh的烛台和音量条 2022-01-01
- 求两个直方图的卷积 2022-01-01
- 在Python中从Azure BLOB存储中读取文件 2022-01-01
- 使用大型矩阵时禁止 Pycharm 输出中的自动换行符 2022-01-01
- Plotly:如何设置绘图图形的样式,使其不显示缺失日期的间隙? 2022-01-01
