其他目的,最后是异常处理

时间:2011-05-18 22:53:23

标签: python

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

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块之外吗?如果是,elsefinally的目的是什么?它只是为了增强可读性吗?

6 个答案:

答案 0 :(得分:56)

我们的想法是尽可能减少处理异常的代码。 else中的任何内容都可以移动到try,是的,但是当你真的希望它被引发时,你最终可能会捕获异常。您可能已成功打开该文件,但如果read导致IOError并且它位于try中,那么该文件也会被捕获。

来自horse's mouth

  

使用else子句比向try子句添加其他代码更好,因为它避免意外捕获由{{1}保护的代码未引发的异常声明。

正如其他两个答案已经说过的那样,try ... except块代码将被执行,无论是否有任何引发的异常,包括{{1}内部}或finally,以及是否处理该异常。规范的用例是确保文件句柄被关闭,无论如何。*

official phrasing

  

else子句中发生异常且尚未由except子句处理(或者在tryexcept子句中发生时),在except子句执行后重新引发它。当else语句的任何其他子句通过finallyfinallytry保留时,break子句也会在“出路”时执行言。


*上下文管理器(continue块)稍微避免了特定的使用。

答案 1 :(得分:46)

无论try块中的语句是失败还是成功,都会执行

finally。仅当try块中的语句不引发异常时才会执行else

答案 2 :(得分:10)

无论发生什么情况,都会执行finally 始终中的阻止。即使未处理异常或异常处理程序本身也会产生新的异常。

答案 3 :(得分:9)

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

print(foo.read())
您的示例中的

会引发IOError,您的第一个代码段将无法捕获该错误,而您的第二个代码段则会出现错误。您尝试尽可能地使try块尽可能小,以便只捕获您想要捕获的异常。

finally块总是被执行,无论如何。例如,如果try块包含return语句,则仍会执行finally块,而整个try / except块下方的任何代码都会获胜“T

答案 4 :(得分:2)

try:
   print("I may raise an exception!")
except:
   print("I will be called only if exception occur!")
else:
   print("I will be called only if exception didn't occur!")
finally:
   print("I will be called always!")

答案 5 :(得分:0)

finally块始终执行

Else块已执行,如果没有任何异常。

我更喜欢将代码放入finally块中,该代码块总是在try之后执行,除了块。

我更喜欢将代码放在else子句没有引发异常的情况下执行的try块中 像这样

最后

try:
  f = open("file.txt")
  f.write("change file")
except:
  print("wrong")
finally:
  f.close()

其他

try:
   f = open("file.txt")
   f.write("change file")
except:
  print("wrong")
else:
  print("log => there is not any exception")
finally:
    f.close()