Python核心技术与实战
景霄
Facebook资深工程师
立即订阅
13891 人已学习
课程目录
已完结 46 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | 从工程的角度深入理解Python
免费
基础篇 (14讲)
01 | 如何逐步突破,成为Python高手?
02 | Jupyter Notebook为什么是现代Python的必学技术?
03 | 列表和元组,到底用哪一个?
04 | 字典、集合,你真的了解吗?
05 | 深入浅出字符串
06 | Python “黑箱”:输入与输出
07 | 修炼基本功:条件与循环
08 | 异常处理:如何提高程序的稳定性?
09 | 不可或缺的自定义函数
10 | 简约不简单的匿名函数
11 | 面向对象(上):从生活中的类比说起
12 | 面向对象(下):如何实现一个搜索引擎?
13 | 搭建积木:Python 模块化
14 | 答疑(一):列表和元组的内部实现是怎样的?
进阶篇 (11讲)
15 | Python对象的比较、拷贝
16 | 值传递,引用传递or其他,Python里参数是如何传递的?
17 | 强大的装饰器
18 | metaclass,是潘多拉魔盒还是阿拉丁神灯?
19 | 深入理解迭代器和生成器
20 | 揭秘 Python 协程
21 | Python并发编程之Futures
22 | 并发编程之Asyncio
23 | 你真的懂Python GIL(全局解释器锁)吗?
24 | 带你解析 Python 垃圾回收机制
25 | 答疑(二):GIL与多线程是什么关系呢?
规范篇 (7讲)
26 | 活都来不及干了,还有空注意代码风格?!
27 | 学会合理分解代码,提高代码可读性
28 | 如何合理利用assert?
29 | 巧用上下文管理器和With语句精简代码
30 | 真的有必要写单元测试吗?
31 | pdb & cProfile:调试和性能分析的法宝
32 | 答疑(三):如何选择合适的异常处理方式?
量化交易实战篇 (8讲)
33 | 带你初探量化世界
免费
34 | RESTful & Socket: 搭建交易执行层核心
35 | RESTful & Socket: 行情数据对接和抓取
36 | Pandas & Numpy: 策略与回测系统
免费
37 | Kafka & ZMQ:自动化交易流水线
38 | MySQL:日志和数据存储系统
39 | Django:搭建监控平台
40 | 总结:Python中的数据结构与算法全景
技术见闻与分享 (4讲)
41 | 硅谷一线互联网公司的工作体验
42 | 细数技术研发的注意事项
加餐 | 带你上手SWIG:一份清晰好用的SWIG编程实践指南
43 | Q&A:聊一聊职业发展和选择
结束语 (1讲)
结束语 | 技术之外的几点成长建议
Python核心技术与实战
登录|注册

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

景霄 2019-07-15
你好,我是景霄。
我想你对 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/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Python核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(29)

  • new
    打开文件时用最方便
    2019-07-15
    6
  • AllenGFLiu
    第一次有教程提到这个上下文管理器,学习。
    对知识的学习就是需要从多角度重复去看,在这个过程中查遗补缺,才能保持不断进步。

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

    2019-07-15
    6
  • enjoylearning
    主要用于数据库连接
    2019-07-15
    5
  • Geek_59f23e
    UnboundLocalError: local variable 'f' referenced before assignment
    最后一个例子有报错哦,基于生成器的上下文管理器那儿,提示说finally语句里的f变量没有先声明。
    2019-07-16
    3
  • 大牛凯
    老师好,请问基于类的上下文,“__enter__“方法什么时候返回self呢?DBConnectionManager的例子中可以说明一下为什么是返回self不是返回self.connection么?
    2019-07-15
    1
    3
  • 瞳梦
    请问数据库的那个例子,__enter__()中返回self.connection是不是更符合实际应用中的情况。
    2019-07-17
    2
  • ajodfaj
    with tf.Session() as sess
    2019-07-15
    2
  • 安排
    是不是只有程序出了with代码块,管理的对象才会析构,也就是释放资源?

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

    2019-07-15
    1
    2
  • Paul Shan
    内存管理Python已经实现,with语句是管理其他类型资源的简便方法。
    2019-11-22
  • 火锅小王子
    现在才学这个专栏 感觉落后了好多同学 想问下老师一个问题 这里讲到了上下文管理器 可不可以分析下async with异步上下文的逻辑和用法 ?一直不是很明白这个点 😀
    2019-11-02
  • Carl
    为什么平时使用 with open() as f 时可以畅通无阻呢?
    是因为open这个函数在源码里就用@contextmanager装饰了吗?
    2019-10-21
  • 自由民
    没用过,以前在c/c++里都是自己释放资源的。最多在类的析构函数里释放,但是这样还是有可能会资源泄露的。
    2019-10-20
  • 丁丁历险记
    超喜欢py 这总把啰哩巴嗦的实现简化的套路。
    2019-10-07
  • Geek_54edc1
    “__enter__()返回FileManager 对象赋给变量f”这里应该写错了,应该是返回资源self.file给变量f
    2019-09-30
  • 温若
    some_lock = threading.Lock()
    with somelock:
        ...

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

    作者回复: 对

    2019-08-03
  • 张洪阆
    with限制了对象的作用域,相当于是个临时对象
    2019-07-28
  • magician
    DBClient用了什么python package?
    2019-07-23
  • 小侠龙旋风
    老师,您好,threading.Lock()案例能否写得详细一点
    2019-07-21
  • Geek_077da0
    老师您好,在DBConnectionManager中的__enter__方法返回的是self,即当前对象,但是在FileManager类的__enter__方法中返回的却是self.file。
    请问究竟是应该返回对象本身,还是应该返回这个对象具体要操作的那个资源呢?希望能得到您的解答。
    2019-07-19
    1
收起评论
29
返回
顶部