异常处理的else
和finally
部分是多余的吗?例如,以下两个代码片段之间是否有任何区别?
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
和finally
的目的是什么?它只是为了增强可读性吗?
答案 0 :(得分:56)
我们的想法是尽可能减少处理异常的代码。 else
块中的任何内容都可以移动到try
,是的,但是当你真的希望它被引发时,你最终可能会捕获异常。您可能已成功打开该文件,但如果read
导致IOError
并且它位于try
中,那么该文件也会被捕获。
使用
else
子句比向try
子句添加其他代码更好,因为它避免意外捕获由{{1}保护的代码未引发的异常声明。
正如其他两个答案已经说过的那样,try ... except
块代码将被执行,无论是否有任何引发的异常,包括{{1}内部}或finally
,以及是否处理该异常。规范的用例是确保文件句柄被关闭,无论如何。*
当
else
子句中发生异常且尚未由except
子句处理(或者在try
或except
子句中发生时),在except
子句执行后重新引发它。当else
语句的任何其他子句通过finally
,finally
或try
保留时,break
子句也会在“出路”时执行言。
*上下文管理器(continue
块)稍微避免了特定的使用。
答案 1 :(得分:46)
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()