Try it and see:
def failure():
raise ValueError, "Real error"
def apologize():
raise TypeError, "Apology error"
try:
failure()
except ValueError:
apologize()
raise
The result:
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
The reason: the "real" error from the original function was already caught by the except
. apologize
raises a new error before the raise
is reached. Therefore, the raise
in the except
clause is never executed, and only the apology's error propagates upward. If apologize
raises an error, Python has no way of knowing that you were going to raise a different exception after apologize
.
Note that in Python 3, the traceback will mention both exceptions, with a message explaining how the second one arose:
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
However, the second exception (the "apology" exception) is still the only one that propagates outward and can be caught by a higher-level except
clause. The original exception is mentioned in the traceback but is subsumed in the later one and can no longer be caught.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…