我不知道为什么我们最终需要尝试……最后陈述。在我看来,这个代码块
try:
run_code1()
except TypeError:
run_code2()
other_code()
和这个finally的用法一样:
try:
run_code1()
except TypeError:
run_code2()
finally:
other_code()
我遗漏了什么吗?
我不知道为什么我们最终需要尝试……最后陈述。在我看来,这个代码块
try:
run_code1()
except TypeError:
run_code2()
other_code()
和这个finally的用法一样:
try:
run_code1()
except TypeError:
run_code2()
finally:
other_code()
我遗漏了什么吗?
当前回答
试着先运行这段代码,不要使用finally块,
1 / 0导致除零误差。
try:
1 / 0
print(1)
except Exception as e:
1 / 0
print(e)
然后尝试运行这段代码,
try:
1 / 0
print(1)
except Exception as e:
1 / 0
print(e)
finally:
print('finally')
对于第一种情况,你没有finally块, 因此,当在except块中发生错误时,程序执行将停止,并且在except块之后不能执行任何东西。
但对于第二种情况, 错误发生,但在程序停止之前,python先执行finally块,然后导致程序停止。 这就是为什么你要用finally来做真正重要的事情。
其他回答
在第一个例子中,如果run_code1()引发了一个不是TypeError的异常,会发生什么?... Other_code()将不会被执行。
与finally: version: other_code()相比,无论引发任何异常,都保证执行。
Finally也可以用于在运行主要工作的代码之前运行“可选”代码,而可选代码可能由于各种原因而失败。
在下面的例子中,我们不知道store_some_debug_info会抛出什么样的异常。
我们可以运行:
try:
store_some_debug_info()
except Exception:
pass
do_something_really_important()
但是,大多数lint会抱怨捕捉到的异常过于模糊。此外,由于我们选择只传递错误,except块并没有真正增加值。
try:
store_some_debug_info()
finally:
do_something_really_important()
上面的代码与第一个代码块具有相同的效果,但更简洁。
代码块是不等效的。如果run_code1()抛出TypeError以外的异常,或者run_code2()抛出异常,finally子句也将运行,而第一个版本中的other_code()在这些情况下不会运行。
最后是“清理行动”的定义。finally子句在离开try语句之前的任何事件中执行,无论是否发生异常(即使您没有处理它)。
我赞同拜尔斯的例子。
您可以使用finally来确保无论是否发生异常都关闭或释放文件或资源,即使您没有捕获异常。(或者如果你没有捕捉到特定的异常。)
myfile = open("test.txt", "w")
try:
myfile.write("the Answer is: ")
myfile.write(42) # raises TypeError, which will be propagated to caller
finally:
myfile.close() # will be executed before TypeError is propagated
在本例中,您最好使用with语句,但这种结构也可以用于其他类型的资源。
几年后,我写了一篇关于滥用finally的博客文章,读者可能会觉得很有趣。