重新抛出python异常.去抓哪个



我正在学习使用python。我刚看到这篇文章:http://nedbatchelder.com/blog/200711/rethrowing_exceptions_in_python.html它描述了在python中重新抛出异常,如下所示:

try:
    do_something_dangerous()
except:
    do_something_to_apologize()
    raise

因为你重新抛出了异常,所以应该有一个外部catch- exception;声明。但是现在,我在想,如果except里面的do_something_to_apologize()抛出了一个错误。哪个会在外部的catch-except中被捕获?你再扔的那个还是do_something_to_apologize()扔的那个?或者优先级最高的异常会首先被捕获?

试试看:

def failure():
    raise ValueError, "Real error"
def apologize():
    raise TypeError, "Apology error"
try:
    failure()
except ValueError:
    apologize()
    raise
结果:

Traceback (most recent call last):
  File "<pyshell#14>", line 10, in <module>
    apologize()
  File "<pyshell#14>", line 5, in apologize
    raise TypeError, "Apology error"
TypeError: Apology error

原因:来自原始函数的"真实"误差已经被except捕获。apologize在到达raise之前抛出一个新的错误。因此,except子句中的raise永远不会被执行,只有道歉的错误向上传播。如果apologize抛出一个错误,Python无法知道你将在apologize之后抛出一个不同的异常。

请注意,在Python 3中,回溯会提到两个异常,并给出一条消息解释第二个异常是如何产生的:

Traceback (most recent call last):
  File "./prog.py", line 9, in <module>
  File "./prog.py", line 2, in failure
ValueError: Real error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "./prog.py", line 11, in <module>
  File "./prog.py", line 5, in apologize
TypeError: Apology error

然而,第二个异常("道歉"异常)仍然是唯一一个向外传播的异常,并且可以被更高级别的except子句捕获。最初的异常在回溯中提到,但被包含在后面的回溯中,无法再被捕获。

do_something_to_apologize()抛出的异常将被捕获。包含raise的行永远不会运行,因为do_something_to_apologize会抛出异常。此外,我不相信python异常中有任何"优先级"的概念。

我认为一个更好的主意是使用

raise NewException("Explain why") from CatchedException

模式。特别是,考虑到Python 3和@BrenBarn给出的例子,我使用以下

def failure():
    raise ValueError("Real error")
try:
    failure()
except ValueError as ex:
    raise TypeError("Apology error") from ex
收益率

--------- ValueError----                                
Traceback (most recent call last) 
      4 try:
----> 5     failure()
      6 except ValueError as ex:
      1 def failure():
----> 2     raise ValueError("Real error")
      3 
ValueError: Real error
The above exception was the direct cause of the following exception:
-----TypeError-----
Traceback (most recent call last) 
      5     failure()
      6 except ValueError as ex:
----> 7     raise TypeError("Apology error") from ex
TypeError: Apology error

最新更新