Python 核心技术与实战
景霄
Facebook 资深工程师
78765 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
Python 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

29 | 巧用上下文管理器和With语句精简代码

你好,我是景霄。
我想你对 Python 中的 with 语句一定不陌生,在专栏里它也曾多次出现,尤其是在文件的输入输出操作中,不过我想,大部分人可能习惯了它的使用,却并不知道隐藏在其背后的“秘密”。
那么,究竟 with 语句要怎么用,与之相关的上下文管理器(context manager)是什么,它们之间又有着怎样的联系呢?这节课,我就带你一起揭开它们的神秘面纱。

什么是上下文管理器?

在任何一门编程语言中,文件的输入输出、数据库的连接断开等,都是很常见的资源管理操作。但资源都是有限的,在写程序时,我们必须保证这些资源在使用过后得到释放,不然就容易造成资源泄露,轻者使得系统处理缓慢,重则会使系统崩溃。
光说这些概念,你可能体会不到这一点,我们可以看看下面的例子:
for x in range(10000000):
f = open('test.txt', 'w')
f.write('hello')
这里我们一共打开了 10000000 个文件,但是用完以后都没有关闭它们,如果你运行该段代码,便会报错:
OSError: [Errno 23] Too many open files in system: 'test.txt'
这就是一个典型的资源泄露的例子。因为程序中同时打开了太多的文件,占据了太多的资源,造成系统崩溃。
为了解决这个问题,不同的编程语言都引入了不同的机制。而在 Python 中,对应的解决方式便是上下文管理器(context manager)。上下文管理器,能够帮助你自动分配并且释放资源,其中最典型的应用便是 with 语句。所以,上面代码的正确写法应该如下所示:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Python 核心技术与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(35)

  • 最新
  • 精选
  • AllenGFLiu
    第一次有教程提到这个上下文管理器,学习。 对知识的学习就是需要从多角度重复去看,在这个过程中查遗补缺,才能保持不断进步。

    作者回复: 嗯嗯,是这样的

    2
    26
  • 安排
    是不是只有程序出了with代码块,管理的对象才会析构,也就是释放资源?

    作者回复: 准确的说释放资源的行为发生在with语句的最后(上下文管理器的__exit__函数内)

    2
    7
  • 火锅小王子
    现在才学这个专栏 感觉落后了好多同学 想问下老师一个问题 这里讲到了上下文管理器 可不可以分析下async with异步上下文的逻辑和用法 ?一直不是很明白这个点 😀

    作者回复: 后面有讲到

    2
  • fly1024
    有个疑问: 对于file和Lock这两个使用with用法,python会自动调用对应释放资源的函数(close和release),这两个释放资源的函数也是定义__exit函数里的吗?希望老师解答一下。

    作者回复: 对

    1
  • Geek_d848f7
    还是不怎么清楚基于生成器的上下文管理器的运行过程

    作者回复: 哪里不明白?文章中应该讲的很清楚了

    1
  • 程序员人生
    老师,最后一段代码执行后报这个错: TypeError: file_manager() missing 1 required positional argument: 'mode' 应该写成这样把, with file_manager('test.txt','w') as f: f.write('hello world2')

    作者回复: 谢谢指正,已更新

  • ajodfaj
    with tf.Session() as sess
    1
    16
  • enjoylearning
    主要用于数据库连接
    15
  • new
    打开文件时用最方便
    13
  • LJK
    老师好,请问基于类的上下文,“__enter__“方法什么时候返回self呢?DBConnectionManager的例子中可以说明一下为什么是返回self不是返回self.connection么?
    2
    8
收起评论
显示
设置
留言
35
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部