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 装饰器,更进?步简化上下管理器的实现?式。