不用管是不是close文件了.
文件太大,比如FAT323格式,最大4G,如果超过了,就写不进去,这样会在close()前面会抛出异常,这样文件就一直没有关闭,会导致文件资源会一直被占用,造成资源泄露,这样就会出现一直打开文件的现象,导致资源泄露.
解决方法:
try: pass except: 错误 else: 正确 finally: close()
打开文件/关闭文件 的中间过程把资源 保存/标记(就是做个记号,表示这个资源文件被使用了,被谁使用,使用到哪一步等) 起来了,这样的情况就称之为上下文.
格式:
打开
资源保存/标记
关闭
""" 自己写一个类,完成with的操作 只要一个类实现上下文管理器,with才能支持 """ class MyFile: """文件类,取代open类,和open类相似""" def __init__(self, name, mode): self.name = name self.mode = mode def __enter__(self): """这是提供资源的上文环境,提供资源 给as后面的变量""" print('正在进入上文获取资源') self.file = open(self.name, self.mode) return self.file def __exit__(self, exc_type, exc_val, exc_tb): """提供下文,关闭资源""" print('正在进入下文,关闭资源') self.file.close() if __name__ == '__main__': """ 1.>obj = MyFile('app.txt','rb') 执行,调用类初始化完成一个对象obj 2.>通过调用对象obj的__enter__方法获取资源<上文> --->给 as 后面的file 3.>with正常代码中 可以正常使用获取到的资源 4.>在退出with语句块的时候,关闭资源的时候调用obj的__exit__方法,进入下文,释放资源 """ with MyFile('app.txt', 'rb') as file: print(file.read(8)) """ 总结: 实现支持with操作的类--->叫上下文管理器 同理 __iter__/__next__的叫 迭代器类 实现__enter__方法 上文: 提供资源 实现__exit__方法 下文: 关闭资源 __enter__:意思就是进入资源 __exit__:意思就是退出资源 """
""" 提供了 创建资源/销毁资源 就是上下文管理器 """ class myFile: """文件类,取代open类,和open类相似""" def __init__(self, name, mode): self.name = name self.mode = mode def __enter__(self): # 获取资源 """这是提供资源的上文环境,提供资源 给as后面的变量""" print('正在进入上文获取资源') self.file = open(self.name, self.mode) return self.file def __exit__(self, exc_type, exc_val, exc_tb): # 关闭资源 """提供下文,关闭资源 exc_type:类型 exc_val:类型值 exc_tb:跟踪返回值 """ print('正在进入下文,关闭资源') # print(exc_type) # <class 'io.UnsupportedOperation'> # print(exc_val) # read # print(exc_tb) # <traceback object at 0x0000024BC9F1F748> self.file.close() if __name__ == '__main__': with myFile('app.txt', 'wb') as file: # 就是把上下文资源管理起来 print(file.read(8))
@contextmanager:
from contextlib import contextmanager # 导入上下文管理器 @contextmanager def myopen(name, mode): """生成器函数 + 装饰器 = 上下文管理器:进入上文,获取资源""" print('正在进入上文获取资源') file = open(name, mode) yield file # 暂停在这里,不能使用return,这样会直接把资源全部关闭 # 进入下文 关闭资源 print('正在进入下文关闭资源') file.close() if __name__ == '__main__': with myopen('app.txt', 'rb') as file: print(file.read(8))