赞
踩
回想一下文件操作,一般文件操作都会面临一个问题:由于读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。所以,为了保证无论是否出错都能正确的关闭文件,我们先使用try… finally来实现
使用try … finally:使用这种方式,无论如何最后文件都会关闭,解决了上述问题,但是代码比较繁琐,我们思考有没有简单的方式
try:
# 1.以读的方式打开文件
f = open('1.txt','r')
# 2.进行文件操作
f.write('xxxxx') # 这一步会引发异常
except IOError as e:
print("文件操作出错",e)
finally:
f.close()
使用这种方式,无论如何最后文件都会关闭,解决了上述问题,但是代码比较繁琐,我们思考有没有简单的方式
使用 with 关键字:这种方式,当文件发生异常时,文件将自动关闭。将f贴给open的返回值,当离开with代码块时,系统可以自动调用f.close()方法,那么它的实现原理是什么值得研究?为了研究这种方式,先需要学习什么是上下文管理器
try:
# 1.以读的方式打开文件
with open('1.txt','r') as f
# 2.进行文件操作
f.write('xxxxx') # 这一步会引发异常,但是由于使用的with,文件会自动关闭,不会捕获异常
except IOError as e: # useless
print("文件操作出错",e)
首先先要理解上下文。这个要怎么理解呢,很抽象,拿文件操作举例,打开文件就相当于上文,操作文件就相当于文中,关闭文件就相当于下文
上下文管理器:上下文管理器本质就是能够支持with操作的类或对象。任何实现了__ enter __ ()和__ exit __()方法的类对象对可以称之为上下文管理器。上下文管理器对象可以使用with关键字对上下文管理,显然,文件(file对象)也实现了上下文管理协议(上面的两个方法)
class MyFile(): # 1. __init__() 初始化方法 def __init__(self,file_name,file_mode): self.file_name = file_name self.file_mode = file_mode # 2. __enter__() 上文方法 def __enter__(self): print("进入上文") self.file = open(self.file_name,self.file_mode) return self.file # 3. __exit__() 下文方法 def __exit__(): print("进入下文") self.file.close() # hello.txt为自己定义的文件 # file 并不是MyFile的一个对象,而是上文__enter__函数返回的内容,是一种资源 with MyFile('hello.txt','r') as file: file_data = file.read() print(file_data) # result 进入上文 这里是你文件里的内容 进入下文
在学习本节之前,请先复习一下生成器和迭代器
通过装饰器@ contextmanager实现上下文管理:
from contextlib import contextmanager @contextmanager def myopen(file_name,file_mode): print("进入上文") # 1.打开资源 file = open(file_name,file_mode) # 2.返回资源 yield file print("进入下文") # 3.关闭资源 file.close() with myopen('hello.txt','r') as file: file_data = file.read() print(file_data)
当然很多人会有疑问,装饰器contextmanager的作用是什么,他就是把enter和exit函数装饰给了myopen函数,使得文件资源得以自动打开退出(如果你进入该装饰器的源码可以看到里边实现了enter和exit函数)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。