如何在 Python(3.8<=) 中重新引发异常?

How active exception to reraise in Python(3.8<=)?

看看这个:

RuntimeError: No active exception to reraise

我用raise。没有这样的错误:

class example:
    def __getattribute__(self, attr_name):
        raise  # I mean: AttributeError: '...' object has no attribute '...'

这是raise statement:

raise_stmt ::=  "raise" [expression ["from" expression]]

表达式是可选的。

我检查了 ,但这不是我的答案。如果错误显示“没有要重新引发的活动异常”,那么我可以激活一个错误。我不知道这个错误是什么意思。我的问题是,“主动异常”是什么意思,它在哪里使用?它是否有助于使代码更短和更优化?是否可以将它用于我在代码中展示的任务?

当你勉强使用raise关键字时,Python尝试在当前范围内重新引发当前发生的异常,如果没有触发异常,你将得到RuntimeError: No active exception to re-raise.

要查看哪个异常处于活动状态(正在处理),您可以使用 sys.exc_info():

import sys

try:
    raise ZeroDivisionError()
except ZeroDivisionError:
    type_, value, tb = sys.exc_info()
    print(type_)  # <class 'ZeroDivisionError'>

在上面的 except 块中,您可以使用裸 raise 关键字,它会为您重新引发 ZeroDivisionError 异常。

如果没有活动异常,sys.exc_info()的返回值为(None, None, None)。所以你必须使用 raise 关键字后跟子类或 BaseException 的实例。 __getattribute__ 方法中的问题就是这种情况,因为没有活动异常。

class Example:
    def __getattribute__(self, attr_name):
        raise AttributeError(f'Error for "{attr_name}".')

obj  = Example()
obj.foo   # AttributeError: Error for "foo".

来自评论:

Active exception表示当前触发的异常,并且在工作流中,如果不捕获它并让它冒泡,它会终止进程.

我可以找到这个来解决我的问题:

“活动异常”是什么意思,用在什么地方?

然后使用 try-except 并且代码转到 except 块,错误激活。 关于使用我们可以检查错误,如果不应该处理,可以使用 raise 没有 arg(即使在函数中)。现在没有引发错误 参考线。我不知道是否有其他方法可以做到这一点,但我相信这个方法。

示例:

>>> try:
...     10 / 0
... except[ ZeroDivisionError[ as err]]:
...     raise
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
>>> def test():
...     raise
... 
>>> try:
...     10 / 0
... except[ ZeroDivisionError[ as err]]:
...     test()
... 
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
  File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
>>> 

它是否有助于使代码更短和更优化?

是的。通过使用这种方法,代码和错误都被缩短了。但是在这种方法中,对异常过程的控制较少,有时会出现问题。

是否可以将它用于我在代码中展示的任务?

没有。必须返回 NotImplemented 才能使上述代码生效。我对此很有信心,但有可能仅此还不够。