Python中当我们们打开文本时,通常会是用with语句,with语句允许我们非常方便的使用资源,而不必担心资源没有关闭。

with open('/path/filename', 'r') as f:
f.read()

  然而,并不是只有open()函数返回fp对象才能使用 with 语句。实际上,任何对象,只要正确实现上下文管理,就可以使用with语句。实现上下文管理是通过 __enter__ 和 __exit__ 这两个方法实现的。例如,下面的class实现了这两个方法:

class Query(object):

    def __init__(self, name):
self.name = name def __enter__(self):
print('Begin')
return self def __exit__(self, exc_type, exc_value, traceback):
if exc_type:
print('Error')
else:
print('End') def query(self):
print('Query info about %s...' % self.name)

  这样我们可以把自己写的资源对象用于 with 语句。

with Query('Bob') as q:
q.query()

  

@contextmanager

  编写 __enter__ 和 __exit__ 仍然很繁琐,因此Python的标准库 contextlib 提供了更简单的写法,上面的代码可以改写为:

from contextlib import contextmanager

class Query(object):

    def __init__(self, name):
self.name = name def query(self):
print('Query info about %s...' % self.name) @contextmanager
def create_query(name):
print('Begin')
q = Query(name)
yield q
print('End')

  @contextmanager 这个装饰器接受一个 generator,用 yield 语句把 with ... as var 把变量输出出去,然后,with 语句就可以正常的工作了:

with create_query('Bob') as q:
q.query()

  很多时候,我们希望在某段代码执行前后自动执行特定代码,也可以用 @contextmanager实现。

@contextmanager
def tag(name):
print("<%s>" % name)
yield
print("</%s>" % name) with tag("h1"):
print("hello")
print("world")

  上述代码执行结果:

<h1>
hello
world
</h1>

  代码的执行顺序是:

  1. with 语句 首先执行 yield 之前的语句,因此打印出 <h1>.
  2. yield 调用会执行 with 语句内部的所有语句,因此打印出 hello 和 world.
  3. 最后执行yield之后的语句,打印出 </h1>.

@closing

  如果一个对象没有实现上下文,就不能使用 with 语句,但是可以用 closing() 来把对象变为上下文对象。

from contextlib import closing
from urllib.request import urlopen with closing(urlopen('https://www.python.org')) as page:
for line in page:
print(line)

  closing 也是一个经过 @contextmanager 装饰的generator

@contextmanager
def closing(thing):
try:
yield thing
finally:
thing.close()

  它的作用就是把任意对象变为上下文对象,并支持 with语句。

本文引用于廖雪峰的博客

Python3之 contextlib的更多相关文章

  1. (转)contextlib — 上下文管理器工具

    原文:https://pythoncaff.com/docs/pymotw/contextlib-context-manager-tool/95 这是一篇社区协同翻译的文章,你可以点击右边区块信息里的 ...

  2. Python 上下文管理器模块--contextlib

    在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...

  3. Python标准模块--ContextManager

    1 模块简介 在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with.with语句允许开发者创建上下文管理器.什么是上下文管理器?上下文管理器就是允许你可以自动地开始和结束一些事情. ...

  4. python 安装第三方库,超时报错--Read timed out.

    Traceback (most recent call last): File "/home/xiaoduc/.pyenv/versions/3.5.0/lib/python3.5/site ...

  5. tensorflow由于未初始化变量所导致的错误

     版权声明:本文为博主原创文章,如需转载请注明出处,谢谢. https://blog.csdn.net/qq_38542085/article/details/78742295 初始代码 import ...

  6. python安装pandas模块

    直接安装时报错了 localhost:~ ligaijiang$ pip3 install pandas Collecting pandas Downloading https://files.pyt ...

  7. python-性能测试

    目录: 1.timeit 1.1 在命令后调用timeit 1.2 在代码中使用 1.3 创建计时器实例,通过autorange获得循环次数 1.4 Wall时间和CPU时间 2.profile和cP ...

  8. celery 4.1下报kombu.exceptions.EncodeError: Object of type 'bytes' is not JSON serializable 处理方式

    #python代码如下 from celery import Celeryimport subprocess app = Celery('tasks', broker='redis://localho ...

  9. VS code MacOS 环境搭建

    环境:MacBook Pro 参考博客 为了动手开发AI代码,我需要安装一个VS code. 开始我以为是安装visual studio呢.我装过visual studio2017. VS code是 ...

随机推荐

  1. ARGB_8888

    原文出处:http://www.cnblogs.com/and_he/archive/2012/12/22/argb.html A:透明度 R:红色 G:绿 B:蓝 Bitmap.Config ARG ...

  2. 由Strurts2漏洞引开谈谈web代码安全问题

    漏洞与补丁齐飞,蓝屏共死机一色. 最近struts2的安全漏洞影响面甚广,此后门为可以在url中直接远程调用脚本的漏洞和一个重定向漏洞.大家可以在s2-016远程执行脚本漏洞和s2-017重定向开放漏 ...

  3. 15-I hate it (HDU1754:线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=1754     相似例题:  敌兵布阵  http://www.cnblogs.com/zhumengdexiao ...

  4. sql2008 安装提示重启失败

    [转] https://www.cnblogs.com/chenshaogang/p/4313022.html

  5. mongoTemplate查询

    1.精确查询用“is” Criteria criteria=new Criteria("namespaceName"); criteria.is(namespaceName); Q ...

  6. 制作alipay-sdk-java包到本地仓库

    项目要用到支付宝的扫码支付,后台使用的maven 问了客服 官方目前没有 maven 的地址只能手动安装到本地了,如果建了maven 服务器也可以上传到服务器上 从支付宝官网上下载sdk 制作本地安装 ...

  7. 【转载】mysql中timestamp,datetime,int类型的区别与优劣

    转载来自souldak,微博:@evagle以下内容整合筛选自互联网: int1. 占用4个字节2. 建立索引之后,查询速度快3. 条件范围搜索可以使用使用between4. 不能使用mysql提供的 ...

  8. MySQL闪退

    把配置文档的如图位置打开

  9. jenkins构建后接受者收不到邮件问题解决方案

    jenkins部署.安装增强版邮件插件,配置邮件及增强版邮件通知请参考网上教程,由于教程比较多页通俗易懂,笔者在这里不做重复说明,本文重点是解决配置好增强版邮件,job构建后仍然收不到邮件的问题 步骤 ...

  10. jmeter - 命令行方式运行

    命令格式: jmeter -n -t <testplan filename> -l <listener filename> 参数说明: -n 非 GUI 模式 -> 在非 ...