为什么我们需要Python中的“finally”语句?
我不知道为什么我们finally
需要try...except...finally
陈述。 在我看来,这个代码块
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() return None # The finally block is run before the method returns finally: other_code()
比较这个:
try: run_code1() except TypeError: run_code2() return None other_code() # This doesn't get run if there's an exception.
其他可能导致差异的情况:
- 如果在except块内引发exception。
- 如果在
run_code1()
引发exception,但它不是TypeError
。 - 其他控制stream程语句,例如
continue
和break
语句。
即使您没有发现exception, 也可以使用finally
来确保文件或资源被closures或释放,而不pipe是否发生exception。 (或者如果你没有捕捉到这个特定的例外。)
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
语句,但是这种结构可以用于其他types的资源。
几年之后,我写了一篇关于滥用finally
哪些读者会觉得有趣的博客文章 。
他们不相同。 最后代码运行,不pipe发生什么事情。 清理必须运行的代码很有用。
代码块是不相同的。 如果run_code1()
抛出一个TypeError
以外的TypeError
,或者run_code2()
抛出exception,而第一个版本中的other_code()
不会在这些情况下运行,则finally
子句也将被运行。
在你的第一个例子中,如果run_code1()
产生一个不是TypeError
的exception,会发生什么? … other_code()
将不会被执行。
与finally:
版本比较: other_code()
保证被执行,不pipe是否引发任何exception。
finally
是定义“清理行动” 。 在离开try
语句之前,无论是否出现exception(即使不处理它), finally
子句都会被执行。
我以@ Byers的例子。
最后还可以在运行“主要工作”的代码之前运行“可选”代码,并且可选代码可能由于各种原因而失败。
在下面的例子中,我们不知道什么样的exceptionstore_some_debug_info
可能抛出。
我们可以运行:
try: store_some_debug_info() except Exception: pass do_something_really_important()
但是,大多数短裤都会抱怨过于模糊的例外。 另外,因为我们select只pass
错误,所以except
块不会真正增加价值。
try: store_some_debug_info() finally: do_something_really_important()
上面的代码与第一个代码块有相同的效果,但更简洁。
完美的例子如下:
try: #x = Hello + 20 x = 10 + 20 except: print 'I am in except block' x = 20 + 30 else: print 'I am in else block' x += 1 finally: print 'Finally x = %s' %(x)