其他目的,最后在exception处理

elsefinally的exception处理部分是多余的? 例如,以下两个代码片段之间是否有区别?

 try: foo = open("foo.txt") except IOError: print("error") else: print(foo.read()) finally: print("finished") 

 try: foo = open("foo.txt") print(foo.read()) except IOError: print("error") print("finished") 

更一般地说, else的内容不能总是被移入try ,而finally的内容不能被移出try / catch块? 如果是的话, else的目的是else ? 这只是为了提高可读性吗?

这个想法是,你保持你正在处理exception的代码尽可能小。 任何在else块中的else 可能会被移到try ,是的,但是当你真的希望它被提出的时候,你可能会遇到一个exception。 你可能已经成功地打开了这个文件,但是如果这个read导致了一个IOError并且它正在try ,那么它也会被捕获。

从马的口中 :

else子句的使用要比向try子句中添加额外的代码要好,因为它避免了意外捕获由try ... except语句保护的代码没有引发的exception。

正如其他两个答案已经说过的那样, finally代码块的代码会被执行,无论是否有任何exception引发,包括elseexcept ,以及是否处理该exception。 这个规范的用例是绝对确保一个文件句柄closures,不pipe是什么。*

这个官方措辞 :

try子句中发生exception并且没有被except子句处理(或者在exceptelse子句中发生了exception)时,在执行了finally子句之后,它将被重新引发。 当try语句的任何其他子句通过breakcontinuereturn语句留下时, finally子句也会在“出路”中执行。


*这种特殊的用途已经被上下文pipe理者( with...as块)略微地消除了。

不pipetry块中的语句是失败还是成功, finally被执行。 else仅在try块中的语句不引发exception时才执行。

不pipe发生什么事情, finally的块总是被执行。 即使没有处理exception,exception处理程序本身也会产生新的exception。

如果将try块中的else块的内容移动,您还将捕获else块期间可能发生的exception。 如果行

 print(foo.read()) 

在你的例子中抛出一个IOError ,你的第一个代码片段将不会捕获该错误,而你的第二个片段将会。 您尽量保持try小的try块,以确保只捕获您想要捕获的exception。

finally块总是被执行,不pipe是什么。 例如,如果try块包含一个return语句, finally块仍然会被执行,而整个try / except块下的任何代码都不会被执行。