- with
with open(file='HelloWorld', mode='r')as f:
print(f.read())
- 没用with
import traceback
f = open(file='HelloWorld', mode='w')
try:
f.write('world: go away')
except:
print(traceback.format_exc())
finally:
f.close()
打开文件在进行读写的时候可能会出现一些异常状况,按 f.open 的写法,是需要try、except、finally,做异常判断的,并且文件是否能执行,都要执行 finally f.close() 关闭文件
with 方法帮我们实现了 finally 中 f.close
finally是什么?
无论 try语句中是否抛出异常,finally中的语句一定会被执行。
f = open(file='HelloWorld', mode='w')
try:
f.write('world: go away')
print(1)
finally:
f.close()
print(2)
不论 try 中写文件的过程中是否有异常,finally 中关闭文件的操作一定会执行。
# 打印结果
1
2
那执行的顺序是什么样的呢?
def func1():
try:
return 1
finally:
return 2
def func2():
try:
raise ValueError()
except:
return 1
finally:
return 3
print(func1())
print(func2())
# 执行结果
2 "func1"
3 "func2"
上个例子中可以看到
- func1的 try 的 return 是没有返回结果的
- func2的 except 的 return 是没有返回结果的
在 python 官网中 对 finally 有这样的解释:
A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. When an exception has occurred in the try clause and has not been handled by an except clause (or it has occurred in a except or else clause), it is re-raised after the finally clause has been executed.
The finally clause is also executed “on the way out” when any other clause of the try statement is left via a break, continue or return statement.
译文:
无论是否发生异常,finally子句总是在离开try语句之前执行。如果在try子句中发生了异常,并且没有被except子句处理(或者在except或else子句中发生了异常),则在finally子句执行后重新引发该异常。当try语句的任何其他子句通过break、continue或return语句离开时,也会“在离开时”执行finally子句。
重点部分用粗体标出了,翻成是 try 块中包含 break、continue 或者 return 语句的,在离开 try 块之前,finally 中的语句也会被执行。
上面的例子:
-
func1() ,在try块return之前,会执行finally中的语句,try中的return被忽略了,最终返回的值是finally中return的值。
-
func2() ,try块中抛出异常,被except捕获,在except块return之前,执行finally中的语句,except中的return被忽略,最终返回的值是finally中return的值。
def func1():
try:
print('func1-try: return 1')
return 1
finally:
print('func1-finally: return 2')
return 2
def func2():
try:
print('func2-try: raise error')
raise ValueError()
except:
print('func2-except: return 1')
return 1
finally:
print('func2-finally: return 3')
return 3
print(func1())
print(func2())
# 打印结果
func1-try: return 1
func1-finally: return 2
2
func2-try: raise error
func2-except: return 1
func2-finally: return 3
3
这样就方便理解多了
当 try 监听的和 except 执行的不是同一个异常时 ?
def func():
try:
print 'try: raise error'
raise ValueError()
except IndexError:
print 'except: IndexError'
return 1
finally:
print 'finally'
return 3
print func()
# 打印结果
in func2 try: raise error
finally
3
-
try 中抛出的异常是 ValueError 类型的,而 except 中定位的是 IndexError 类型的,try 中抛出的异常没有被捕获到,所以 except 中的语句没有被执行,但不论异常有没有被捕获,finally 还是会执行,最终函数返回了 finally 中的返回值 3。
-
try 中抛出的异常没有被捕获到,按理说当 finally 执行完毕后,应该被再次抛出,但 finally 里执行了 return,导致异常被丢失。
可以看到在 finally 中使用 return 会导致很多问题。实际应用中,不推荐在 finally 中使用 return 返回。
来源:强哥 公众号:Python与数据分析 链接:
finally介绍转自:https://blog.csdn.net/gyniu/article/details/80345160