多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 使用with 一般文件处理是这样 ~~~ def m2(): f = open('./output.txt', 'w') try: f.write('py') except IOError: print('error') finally: f.close() m2() ~~~ 用with 一种更加简洁,优雅的方式就是with关键字 open方法的返回值赋值给变量f,当离开with代码块的时候,系统自动调用`f.close()`方法 with的作用和使用try/finally语句是一样的 ~~~ def m2(): with open('./output.txt', 'w') as f: f.write('py') m2() ~~~ # 上下文管理器 任何实现了`__enter__()`和`__exit__()`方法的对象都可以称为上下文管理器,上下文管理器对象可以使用with关键字.显然文件file对象也实现了上下文管理器 我们模拟一个 ~~~ class File(object): def __init__(self, filename, mode): self.filename = filename self.mode = mode def __enter__(self): print('enter....') self.f = open(self.filename, self.mode) return self.f def __exit__(self, **args): print('will exit') self.f.close() ~~~ `__enter__()`方法返回资源对象,这里就是你要打开的那个对象文件 `__exit__()`方法处理一些清除工作 因为这个类实现了上下文管理器,我们可以使用with了 ~~~ with File('./output.txt', 'w') as f: print('writing') f.write('java') ~~~ # 另一种方式实现上下文管理 python还提供一个contextmanager的装饰器,更进一步简化了上下文管理器的实现方式.通过yield将函数分割成两部分. yield之前的语句在`__enter__`方法执行,yield以后的语句在__exit__方法中执行. 紧跟在yield后面的是函数的返回值 ~~~ from contextlib import contextmanager @contextmanager def my_open(path, mode): f = open(path, mode) yield f f.close() ~~~ 调用 ~~~ with my_open('output.txt', 'w') as f: f.write('hello') ~~~