Python进阶系列(十七)

举报
zhulin1028 发表于 2022/06/29 01:14:18 2022/06/29
【摘要】 上下文管理器(Context managers) 上下文管理器允许你在有需要的时候,精确地分配和释放资源。 使用上下文管理器最广泛的案例就是with语句了。 想象下你有两个需要结对执行的相关操作,然后还要在它们中间放置一段代码。 上下文管理器就是专门让你做这种事情的。举个例子: with open('some_file',...

上下文管理器(Context managers)

上下文管理器允许你在有需要的时候,精确地分配和释放资源。

使用上下文管理器最广泛的案例就是with语句了。

想象下你有两个需要结对执行的相关操作,然后还要在它们中间放置一段代码。

上下文管理器就是专门让你做这种事情的。举个例子:


  
  1. with open('some_file', 'w') as opened_file:
  2.     opened_file.write('Hola!')

上面这段代码打开了一个文件,往里面写入了一些数据,然后关闭该文件。如果在往文件写数据时发生异常,它也会尝试去关闭文件。上面那段代码与这一段是等价的:


  
  1. file = open('some_file', 'w')
  2. try:
  3.     file.write('Hola!')
  4. finally:
  5.     file.close()

当与第一个例子对比时,我们可以看到,通过使用with,许多样板代码(boilerplate code)被消掉了。 这就是with语句的主要优势,它确保我们的文件会被关闭,而不用关注嵌套代码如何退出。

上下文管理器的一个常见用例,是资源的加锁和解锁,以及关闭已打开的文件(就像我已经展示给你看的)。

让我们看看如何来实现我们自己的上下文管理器。这会让我们更完全地理解在这些场景背后都发生着什么。

基于类的实现

一个上下文管理器的类,最起码要定义__enter__和__exit__方法。

让我们来构造我们自己的开启文件的上下文管理器,并学习下基础知识。


  
  1. class File(object):
  2.     def __init__(self, file_name, method):
  3.         self.file_obj = open(file_name, method)
  4.     def __enter__(self):
  5.         return self.file_obj
  6.     def __exit__(self, type, value, traceback):
  7.         self.file_obj.close()

通过定义__enter__和__exit__方法,我们可以在with语句里使用它。我们来试试:


  
  1. with File('demo.txt', 'w') as opened_file:
  2.     opened_file.write('Hola!')

我们的__exit__函数接受三个参数。这些参数对于每个上下文管理器类中的__exit__方法都是必须的。我们来谈谈在底层都发生了什么。

    1. with语句先暂存了File类的__exit__方法

    2. 然后它调用File类的__enter__方法

    3. __enter__方法打开文件并返回给with语句

    4. 打开的文件句柄被传递给opened_file参数

    5. 我们使用.write()来写文件

    6. with语句调用之前暂存的__exit__方法

    7. __exit__方法关闭了文件

文章来源: zhulin1028.blog.csdn.net,作者:zhulin1028,版权归原作者所有,如需转载,请联系作者。

原文链接:zhulin1028.blog.csdn.net/article/details/125112201

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。