with与上下文管理器
with的用法:
with open代码块结束,会自动调用close关闭文件。
1 try: 2 # 1、以读的?式打开?件 3 with open("1.txt", "r") as f: 4 # 2、读取?件内容 5 f.write("xxxxx") 6 except IOError as e: 7 print("?件操作出错", e)
程序中的上下文:
程序中的上下文和文章的上下文类似,指的是程序段之间的联系,这种联系是某种需要的关联操作,如打开资源,关闭资源。
上下?管理器
上下?管理器本质就是能够?持with操作。 任何实现了 __enter__() 和 __exit__() ?法的对象都可称之为上下?管理器,上下?管理器对象可以使? with 关键字。显然,?件(open)对象也实现了上下?管理器协议。1 class Myopen(object): 2 def __init__(self, file_name, file_mode): 3 self.file_name = file_name 4 self.file_mode = file_mode 5 6 def __enter__(self): 7 self.file = open(self.file_name, self.file_mode) 8 print('进入上文') 9 return self.file 10 11 def __exit__(self, exc_type, exc_val, exc_tb): 12 self.file.close() 13 print('进入下文')
上下文管理器通过with使用:
1 if __name__ == '__main__': 2 try: 3 with Myopen('爬虫电影.txt', 'r') as f: 4 while True: 5 context = f.read(10) 6 if not context: 7 break 8 print(context, end='') 9 except Exception as e: 10 print(e)
上下文管理器除了可以通过类的__enter__()和__exit__()方法实现,还能通过生成器实现,因为生成器拥有类似的性质:在yield之前执行上文,退出上文唤醒生成器,在下文中执行yield之后的部分。
生成器的方式通过一个contextmanager的装饰器实现:
1 @contextmanager 2 def Myopen(file_name, file_mode): 3 f = open(file_name, file_mode) 4 yield f 5 f.close()
使用方法和上文一致。
总结
- Python 提供了 with 语法?于简化资源操作的后续清除操作,实现原理建?在上下?管理器协议
- (实现__enter__和__exit__)之上
- with使?代码中如果在打开过程中发?异常,需要使?try-except进?捕获
- Python 还提供了?个 contextmanager 装饰器,更进?步简化上下管理器的实现?式。