我正在学习使用Python。我刚刚看到这篇文章: http://nedbatchelder.com/blog/200711/rethroing_exceptions_in_python.html 它描述了Python中重新抛出异常,如下所示:
try:
do_something_dangerous()
except:
do_something_to_apologize()
raise
既然重新抛出异常,就应该有一个“外部catch-except”语句。但现在,我在想,如果 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
引发新错误。 因此,
raise
子句中的
except
永远不会执行,只有道歉的错误向上传播。 如果
apologize
引发错误,Python 无法知道您将在
apologize
之后引发不同的异常。请注意,在 Python 3 中,回溯将提及
both 异常,并有一条消息解释第二个异常是如何出现的:
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
子句捕获。 原始异常在回溯中提到,但被包含在后面的异常中并且无法再捕获。
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
您还可以通过从 None 引发新异常来抑制原始异常上下文。代码将更改为
def failure():
raise ValueError("Real error")
try:
failure()
except ValueError as ex:
raise TypeError("Apology error") from None
..它产生以下输出
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[2], line 7
5 failure()
6 except ValueError as ex:
----> 7 raise TypeError("Apology error") from None
TypeError: Apology error