当我们在使用Python时,finally
语句用于定义无论是否发生异常都必须执行的代码块。正常情况下,finally
语句不会捕获异常,而是在异常处理完成后执行。如果这时候finally
语句中发生了异常,它会覆盖之前的异常,并成为最终的异常。要捕获finally
语句中的异常消息,可以使用try
和except
语句包裹finally
块。但是具体问题具体对待,具体情况请看我一一解释。
1、问题背景
在 Python 中,如果需要捕获异常并打印所返回的消息,可以像这样:
class SelfDefinedException(Exception): pass
try:
message = "Hello World!"
raise SelfDefinedException(message)
except MyDefinedException, e:
print "MyDefinedException", e
但这只有在 try
语句中才有效。那么,如何在 finally
子句中捕获和打印信息呢?
class SelfDefinedException(Exception): pass
try:
message = "Hello World!"
raise SelfDefinedException(message)
except MyDefinedException, e:
print "MyDefinedException", e
finally:
# What goes here? So I can see what went wrong?
从一些答案中可以得知,这是不可能的。那么,如果像这样呢?
class SelfDefinedException(Exception): pass
try:
message = "Hello World!"
raise SelfDefinedException(message)
except MyDefinedException, e:
print "MyDefinedException", e
except Exception, e:
# Hopefully catches all messages except for the one of MyDefinedException
print "Unexpected Exception raised:", e
2、解决方案
根据Python文档,你不能在 finally
子句中访问异常信息。因此最好在 except
子句中进行检查。
所以,如果需要捕获所有内容,可以使用:
try:
foo()
except:
print sys.exc_info()
raise
但是这样做几乎总是错误的。因为如果你不知道发生了哪种异常,就无法对其采取任何措施。此时,程序应该关闭并提供尽可能多的关于问题的信息。
当然,也有一些方法可以实现捕获 finally
子句中的异常消息。
例如,创建一个布尔变量 caught_exception
,并在 try
语句中对其赋值为 None
,并在 finally
中检查其值。如果该值不为 None
,则说明发生了异常,此时可以获取异常消息并重新抛出。
caught_exception=None
try:
x = 10/0
#return my_function()
except Exception as e:
caught_exception = e
finally:
if caught_exception:
#Do stuff when exception
raise # re-raise exception
print "No exception"
或者,可以使用 logging
模块将异常消息记录到日志文件中,这样就可以在以后进行查看。
import logging
try:
# Do something that might raise an exception
except Exception as e:
logging.exception("An error occurred:")
finally:
# Do something whether an exception occurred or not
代码例子:
# Define a custom exception
class MyException(Exception):
def __init__(self, message):
self.message = message
# Create a function that raises an exception
def my_function():
raise MyException("This is an exception message")
try:
my_function()
except MyException as e:
print(f"Caught exception: {e.message}")
finally:
print("This will always be printed, regardless of whether an exception was raised or not.")
在这个例子中,try
语句块中调用了 my_function()
函数,该函数会引发 MyException
。except
语句块捕获了这个异常,并打印了异常消息。finally
语句块在 try
语句块和 except
语句块之后执行,无论是否发生了异常,它都会被执行。
总体来说,想要捕获finally
块中的异常消息,这就需要我们在finally
块内使用另一个try
和except
语句来捕获可能发生的异常。如果有更多得问题可以评论区留言讨论。