1. 什么是try finally
在Python中,try-finally语句用于将一些代码封装在try块中,并为无论try块中的代码是否成功运行,都要运行finally块中的代码提供了一种结构化的方式。
try-finally语句的基本语法如下:
try:
# 执行代码
finally:
# 不管try块中代码是否成功执行,都会执行这段代码
在这个语法中,try块是用来包含需要执行的代码,而finally块中则包含了在try块执行完成后一定会被执行的代码。如果try块中的代码执行成功,则可以继续执行后续的代码;如果试图执行try块中的代码失败,则会抛出异常,并跳转到最近的异常处理程序或将异常传播到顶层。无论如何,finally块中的代码都会被执行。
2. 为什么try finally不报错
2.1 try块中代码抛出异常但被except捕获
在try块中,如果代码抛出异常但被except块捕获并处理掉,那么异常不会向上抛出,而是由except块接管,继续执行之后的代码,这意味着finally块中的代码不会被跳过。
try:
# 可能产生异常的代码
1 / 0
except ZeroDivisionError:
# 处理异常的代码
pass
finally:
# 不管try块中的代码是否成功执行,都会执行这段代码
print("finally")
在这个示例中,try块中的代码会抛出ZeroDivisionError异常,但被except块捕获,因此程序不会中断执行,而是继续执行finally块中的代码。程序会输出"finally"。
2.2 try块中代码引发异常但没有被处理
如果try块中的代码引发异常,但没有被任何except块处理掉,那么程序会中止执行,并且异常会向上抛出。在这种情况下,finally块中的代码也不会被跳过。
try:
# 可能产生异常的代码
1 / 0
finally:
# 不管try块中的代码是否成功执行,都会执行这段代码
print("finally")
在这个示例中,try块中的代码会抛出ZeroDivisionError异常,但没有任何except块捕获,因此程序会中止执行,不会输出任何内容。
2.3 程序强制退出
在某些情况下,程序可能会强制退出,比如使用sys.exit()函数,或者在调试过程中使用ctrl-C等方式中断程序执行。在这种情况下,finally块中的代码也不会被跳过。
import sys
try:
# 可能会产生异常的代码
sys.exit(0)
finally:
# 不管try块中的代码是否成功执行,都会执行这段代码
print("finally")
在这个示例中,try块中的代码使用sys.exit()函数强制退出程序,不会输出任何内容。
2.4 程序崩溃
在极少数情况下,可能会发生Python解释器崩溃的情况,比如运行的机器内存耗尽,操作系统崩溃等等。在这种情况下,Python解释器会非正常退出,也就不会执行finally块中的代码。
3. 示例代码
以下是一个完整的示例代码,其中包含了不同情况下finally块中代码的输出结果。
import sys
# 情况1:try块中代码抛出异常但被except捕获
try:
# 可能产生异常的代码
1 / 0
except ZeroDivisionError:
# 处理异常的代码
pass
finally:
# 不管try块中的代码是否成功执行,都会执行这段代码
print("finally 1")
# 情况2:try块中代码引发异常但没有被处理
try:
# 可能产生异常的代码
1 / 0
finally:
# 不管try块中的代码是否成功执行,都会执行这段代码
print("finally 2")
# 情况3:程序强制退出
try:
# 可能会产生异常的代码
sys.exit(0)
finally:
# 不管try块中的代码是否成功执行,都会执行这段代码
print("finally 3")
# 情况4:程序崩溃
try:
# 可能会导致程序崩溃的代码
b = ['1', '2', '3']
print(b[10])
finally:
# 不管try块中的代码是否成功执行,都会执行这段代码
print("finally 4")
以上程序输出的结果如下:
finally 1
finally 2
finally 3
可以看到,只有在情况1、情况2、情况3下finally块中的代码才会被执行,也就是在try块中的代码引发异常但被except捕获、引发异常但没有被处理、程序强制退出的情况下。而在情况4下程序崩溃,finally块中的代码没有被执行。
总结
try-finally语句提供了一种结构化的方式,可以封装一些代码,无论其是否成功执行,都能在最后执行finally块中的代码。其主要应用场景是在资源管理、程序调试等方面,可以确保资源的正常释放和一些必要的清理工作。在使用try-finally语句时,需要考虑到可能发生的各种情况,并根据具体情况处理异常或退出程序等。