为什么我们需要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程语句,例如continuebreak语句。

即使您没有发现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)