29 | 巧用上下文管理器和With语句精简代码
景霄
该思维导图由 AI 生成,仅供参考
你好,我是景霄。
我想你对 Python 中的 with 语句一定不陌生,在专栏里它也曾多次出现,尤其是在文件的输入输出操作中,不过我想,大部分人可能习惯了它的使用,却并不知道隐藏在其背后的“秘密”。
那么,究竟 with 语句要怎么用,与之相关的上下文管理器(context manager)是什么,它们之间又有着怎样的联系呢?这节课,我就带你一起揭开它们的神秘面纱。
什么是上下文管理器?
在任何一门编程语言中,文件的输入输出、数据库的连接断开等,都是很常见的资源管理操作。但资源都是有限的,在写程序时,我们必须保证这些资源在使用过后得到释放,不然就容易造成资源泄露,轻者使得系统处理缓慢,重则会使系统崩溃。
光说这些概念,你可能体会不到这一点,我们可以看看下面的例子:
这里我们一共打开了 10000000 个文件,但是用完以后都没有关闭它们,如果你运行该段代码,便会报错:
这就是一个典型的资源泄露的例子。因为程序中同时打开了太多的文件,占据了太多的资源,造成系统崩溃。
为了解决这个问题,不同的编程语言都引入了不同的机制。而在 Python 中,对应的解决方式便是上下文管理器(context manager)。上下文管理器,能够帮助你自动分配并且释放资源,其中最典型的应用便是 with 语句。所以,上面代码的正确写法应该如下所示:
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文深入探讨了如何巧妙运用上下文管理器和With语句来简化Python代码。通过介绍上下文管理器的概念和作用,以及使用With语句和上下文管理器来简化文件操作和线程锁的代码,读者可以快速了解并应用上下文管理器。文章还介绍了基于类和基于生成器的两种上下文管理器的实现方式,并分析了它们的优缺点。强调了无论使用哪种方式,都需要在`__exit__()`方法或finally块中释放资源。总的来说,本文内容涵盖了上下文管理器的基本概念、实现方式和使用场景,对于想要快速了解并应用上下文管理器的读者来说,是一篇技术特点突出的文章。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Python 核心技术与实战》,新⼈⾸单¥59
《Python 核心技术与实战》,新⼈⾸单¥59
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(35)
- 最新
- 精选
- AllenGFLiu第一次有教程提到这个上下文管理器,学习。 对知识的学习就是需要从多角度重复去看,在这个过程中查遗补缺,才能保持不断进步。
作者回复: 嗯嗯,是这样的
2019-07-15227 - 安排是不是只有程序出了with代码块,管理的对象才会析构,也就是释放资源?
作者回复: 准确的说释放资源的行为发生在with语句的最后(上下文管理器的__exit__函数内)
2019-07-1529 - fly1024有个疑问: 对于file和Lock这两个使用with用法,python会自动调用对应释放资源的函数(close和release),这两个释放资源的函数也是定义__exit函数里的吗?希望老师解答一下。
作者回复: 对
2019-08-033 - 火锅小王子现在才学这个专栏 感觉落后了好多同学 想问下老师一个问题 这里讲到了上下文管理器 可不可以分析下async with异步上下文的逻辑和用法 ?一直不是很明白这个点 😀
作者回复: 后面有讲到
2019-11-022 - Geek_d848f7还是不怎么清楚基于生成器的上下文管理器的运行过程
作者回复: 哪里不明白?文章中应该讲的很清楚了
2019-07-151 - 程序员人生老师,最后一段代码执行后报这个错: TypeError: file_manager() missing 1 required positional argument: 'mode' 应该写成这样把, with file_manager('test.txt','w') as f: f.write('hello world2')
作者回复: 谢谢指正,已更新
2019-07-15 - ajodfajwith tf.Session() as sess2019-07-15116
- enjoylearning主要用于数据库连接2019-07-1515
- new打开文件时用最方便2019-07-1513
- LJK老师好,请问基于类的上下文,“__enter__“方法什么时候返回self呢?DBConnectionManager的例子中可以说明一下为什么是返回self不是返回self.connection么?2019-07-1528
收起评论