更好的语法用于仅在发生异常时重新抛出异常?
我发现自己在想要捕捉一个错误时,总是会先运行一些特定的代码,然后再把原来的错误抛出来:
try:
error = False
# do something that *might* raise an exception
except Exception:
error = True
finally:
# something I *always* want to run
if error:
raise
我使用这个标志是因为如果没有之前的错误直接调用 raise
,就会出现一个 TypeError
错误。有没有更符合 Python 风格的方法来做到这一点,而不需要这个标志呢?
2 个回答
3
finally
这部分代码会始终执行,无论在 try
或 except
代码块中发生了什么,或者 except
代码块是否存在。
这两种写法都可以正常工作:
try:
# do something that *might* raise an exception
finally:
# something I *always* want to run
try:
# do something that *might* raise an exception
except Exception:
raise
finally:
# something I *always* want to run
10
在异常处理器中重新抛出异常:
try:
# do something that *might* raise an exception
except Exception:
raise
finally:
# something I *always* want to run
finally
代码块会始终执行,无论你是否重新抛出了异常。
根据文档:
如果有
finally
,它就指定了一个“清理”处理器。try
代码块会执行,包括任何except
和else
代码块。如果在这些代码块中发生了异常并且没有被处理,这个异常会暂时保存。然后执行finally
代码块。如果有保存的异常,它会在finally
代码块结束时被重新抛出。
注意,如果 finally
代码块使用了 break
或 return
语句,保存的异常会被丢弃:
如果
finally
代码块执行了返回或跳出语句,保存的异常会被丢弃:def f(): try: 1/0 finally: return 42 >>> f() 42
但是如果你在 try
代码块中使用了 break
、continue
或 return
,finally
代码块仍然会被执行:
当在
try
...finally
语句的try
代码块中执行return
、break
或continue
语句时,finally
代码块也会在“退出时”被执行。
注意,在 Python 2.5 之前,你甚至不能在同一个 try
语句中结合使用 except
和 finally
代码块;请参见PEP 341: 统一的 try/except/finally。那时,你需要嵌套 try
语句:
try:
try:
# some code that could raise an exception
except SomeException:
# exception handler
finally:
# cleanup code, always executed