41

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

try:
    do_something_dangerous()
except:
    do_something_to_apologize()
    raise

由于您重新抛出异常,因此应该有一个“外部 catch-except”语句。但是现在,我在想,如果do_something_to_apologize()里面的 except 抛出错误怎么办。哪一个将被捕获在外部“catch-except”中?你重新扔的那个还是被扔的那个do_something_to_apologize()?还是先捕获优先级最高的异常?

4

2 回答 2

75

试试看:

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引发一个新错误。因此,in子句永远不会执行,只有道歉的错误会向上传播。如果引发错误,Python 无法知道您将在.raiseraiseexceptapologizeapologize

请注意,在 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子句捕获。回溯中提到了原始异常,但包含在后面的异常中,无法再被捕获。

于 2014-07-28T18:40:22.180 回答
8

do_something_to_apologize() 抛出的异常将被捕获。由于 do_something_to_apologize 引发的异常,包含 raise 的行将永远不会运行。另外,我不相信 python 异常中有任何“优先级”的想法。

于 2014-07-28T18:38:49.727 回答