浅淡 python 中 with 的用法,上下文管理器
上下文管理器
任何实现了 enter() 和 exit() 方法的对象都可称之为上下文管理器,上下文管理器对象可以使用 with 关键字。显然,文件(file)对象也实现了上下文管理器。
那么文件对象是如何实现这两个方法的呢?我们可以模拟实现一个自己的文件类,让该类实现 enter() 和 exit() 方法。
enter() 方法返回资源对象,这里就是你将要打开的那个文件对象,exit() 方法处理一些清除工作。
因为 File 类实现了上下文管理器,现在就可以使用 with 语句了。
这样,你就无需显示地调用 close 方法了,由系统自动去调用,哪怕中间遇到异常 close 方法也会被调用。
实现上下文管理器的另外方式
Python 还提供了一个 contextmanager 的装饰器,更进一步简化了上下文管理器的实现方式。通过 yield 将函数分割成两部分,yield 之前的语句在 enter 方法中执行,yield 之后的语句在 exit 方法中执行。紧跟在 yield 后面的值是函数的返回值。
调用
总结
Python 提供了 with 语法用于简化资源操作的后续清除操作,是 try/finally 的替代方法,实现原理建立在上下文管理器之上。此外,Python 还提供了一个 contextmanager 装饰器,更进一步简化上下管理器的实现方式。
拓展文章:
1.浅淡 python 中 with 的用法,上下文管理器
(1) 当 with 遇到上下文管理器,就会在执行语句体之前,先执行上下文管理器的 enter 方法,然后再执行语句体,执行完语句体后,最后执行 exit 方法
(2) 使用了 with 语句,不管在处理文件过程中是否发生异常,都能保证 with 语句执行完毕后已经关闭了打开的文件句柄
(3)调用上下文管理器的 enter 方法时;如果使用了 as 子句,则将 enter() 方法的返回值赋值给 as 子句中的目标
with 后面必须跟一个上下文管理器,如果使用了 as,则是把上下文管理器的 __enter__() 方法的返回值赋值给 target,target 可以是单个变量,或者由“()”括起来的元组(不能是仅仅由“,”分隔的变量列表,必须加“()”)
(4) 出现异常时,如果 __exit__ 返回 False(默认不写返回值时,即为 False),则会重新抛出异常,让 with 之外的语句逻辑来处理异常,这也是通用做法;如果返回 True,则忽略异常,不再对异常进行处理
(5)with 只能配合上下文管理器使用,常见的上下文管理器有
2. with 上下文管理器
contextlib 模块
contextlib 模块提供了 3 个对象:装饰器 contextmanager、函数 nested 和上下文管理器 closing。使用这些对象,可以对已有的生成器函数或者对象进行包装,加入对上下文管理协议的支持,避免了专门编写上下文管理器来支持 with 语句。
装饰器 contextmanager
contextmanager 用于对生成器函数进行装饰,生成器函数被装饰以后,返回的是一个上下文管理器,其 enter() 和 exit() 方法由 contextmanager 负责提供,而不再是之前的迭代子。被装饰的生成器函数只能产生一个值,否则会导致异常 RuntimeError;产生的值会赋值给 as 子句中的 target,如果使用了 as 子句的话。
3.上下文管理器
https://blog.csdn.net/weixin_38853600/article/details/82887907
版权声明: 本文为 InfoQ 作者【极客新人】的原创文章。
原文链接:【http://xie.infoq.cn/article/a269f860f375f994a20988cbc】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论