python内置模块之上下文管理contextlib


Posted in Python onJune 14, 2022

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("" % name)
 
with tag("h1"):
    print("hello")
    print("world")

上述代码执行结果:

hello
world
</h1>

代码的执行顺序是:

  • with 语句 首先执行 yield 之前的语句,因此打印出.
  • yield 调用会执行 with 语句内部的所有语句,因此打印出 hello 和 world.
  • 最后执行yield之后的语句,打印出.

二、@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语句。

到此这篇关于python内置模块之上下文管理contextlib的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现豆瓣图片下载的方法
May 25 Python
python使用两种发邮件的方式smtp和outlook示例
Jun 02 Python
对python GUI实现完美进度条的示例详解
Dec 13 Python
使用turtle绘制五角星、分形树
Oct 06 Python
关于python 跨域处理方式详解
Mar 28 Python
Django中ORM找出内容不为空的数据实例
May 20 Python
利用Python实现斐波那契数列的方法实例
Jul 26 Python
Python 如何操作 SQLite 数据库
Aug 17 Python
Python判断变量是否是None写法代码实例
Oct 09 Python
Python根据字符串调用函数过程解析
Nov 05 Python
BeautifulSoup中find和find_all的使用详解
Dec 07 Python
Python 一键获取电脑浏览器的账号密码
May 11 Python
Python时间操作之pytz模块使用详解
Django框架之路由用法
Jun 10 #Python
深入理解pytorch库的dockerfile
Jun 10 #Python
如何利用python实现列表嵌套字典取值
Jun 10 #Python
python中filter,map,reduce的作用
Jun 10 #Python
Django框架中模型的用法
Jun 10 #Python
Django框架中视图的用法
Jun 10 #Python
You might like
YB217、YB235、YB400浅听
2021/03/02 无线电
印尼林东PWN黄金曼特宁咖啡豆:怎么冲世界上最醇厚的咖啡冲煮教程
2021/03/03 冲泡冲煮
php获取url参数方法总结
2014/11/13 PHP
使用PHP similar text计算两个字符串相似度
2015/11/06 PHP
PHP使用curl函数发送Post请求的注意事项
2016/11/26 PHP
js宝典学习笔记(上)
2007/01/10 Javascript
javascript URL编码和解码使用说明
2010/04/12 Javascript
关于jquery ajax 调用带参数的webservice返回XML数据一个小细节
2012/07/31 Javascript
浅谈JavaScript超时调用和间歇调用
2015/08/30 Javascript
AngularJS入门教程之模块化操作用法示例
2016/11/02 Javascript
JavaScript requestAnimationFrame动画详解
2017/09/14 Javascript
JS实现数组简单去重及数组根据对象中的元素去重操作示例
2018/01/05 Javascript
微信小程序实现人脸检测功能
2018/05/25 Javascript
layui实现点击按钮给table添加一行
2018/08/10 Javascript
jQuery实现的简单拖拽功能示例【测试可用】
2018/08/14 jQuery
基于JavaScript实现控制下拉列表
2020/05/08 Javascript
vue cli3.0打包上线静态资源找不到路径的解决操作
2020/08/03 Javascript
antd vue table跨行合并单元格,并且自定义内容实例
2020/10/28 Javascript
Python判断文本中消息重复次数的方法
2016/04/27 Python
Python使用matplotlib填充图形指定区域代码示例
2018/01/16 Python
对numpy 数组和矩阵的乘法的进一步理解
2018/04/04 Python
详谈Python3 操作系统与路径 模块(os / os.path / pathlib)
2018/04/26 Python
python默认参数调用方法解析
2020/02/09 Python
如何在django中实现分页功能
2020/04/22 Python
python归并排序算法过程实例讲解
2020/11/04 Python
python解包概念及实例
2021/02/17 Python
HTML5 Canvas实现文本对齐的方法总结
2016/03/24 HTML / CSS
FORZIERI澳大利亚站:全球顶级奢华配饰精品店
2016/12/31 全球购物
美国在线鲜花速递:ProFlowers
2017/01/05 全球购物
J.Crew官网:美国知名休闲服装品牌
2017/05/19 全球购物
澳大利亚拥有最好的家具和家居用品在线目的地:Nestz
2019/02/23 全球购物
戴尔英国翻新电脑和电子产品:Dell UK Refurbished Computers
2019/07/30 全球购物
工业设计专业推荐信
2013/10/29 职场文书
2015年小学生新年寄语
2014/12/08 职场文书
小学二年级班主任工作经验交流材料
2015/11/02 职场文书
Pytorch中的数据集划分&正则化方法
2021/05/27 Python