Python“从”提升“用法 [英] Python "raise from" usage

查看:127
本文介绍了Python“从”提升“用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


$ b c c c> $ b

  try:
raise ValueError
除了例外为e:
raise IndexError
pre>

它产生

 追溯(最近最近的电话): 
文件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 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: > 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆