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 相关文章推荐
socket + select 完成伪并发操作的实例
Aug 15 Python
简单的python协同过滤程序实例代码
Jan 31 Python
Python中一行和多行import模块问题
Apr 01 Python
对Python 获取类的成员变量及临时变量的方法详解
Jan 22 Python
python调用自定义函数的实例操作
Jun 26 Python
python 求某条线上特定x值或y值的点坐标方法
Jul 09 Python
使用python和pygame制作挡板弹球游戏
Dec 03 Python
python代码如何实现余弦相似性计算
Feb 09 Python
初学者学习Python好还是Java好
May 26 Python
pytorch随机采样操作SubsetRandomSampler()
Jul 07 Python
Python 如何创建一个简单的REST接口
Jul 30 Python
Python数据模型与Python对象模型的相关总结
Jan 26 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
手冲咖啡应该是现代精品咖啡店的必备选项吗?
2021/03/03 冲泡冲煮
PHP读MYSQL中文乱码的解决方法
2006/12/17 PHP
Laravel实现ApiToken认证请求
2019/10/14 PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
2019/11/21 PHP
window.open不被拦截的实现代码
2012/08/22 Javascript
javascript如何判断输入的url是否正确
2014/04/11 Javascript
jQuery使用before()和after()在元素前后添加内容的方法
2015/03/26 Javascript
jq实现左滑显示删除按钮,点击删除实现删除数据功能(推荐)
2016/08/23 Javascript
JS实现拖拽的方法分析
2016/12/20 Javascript
js读取json文件片段中的数据实例
2017/03/09 Javascript
JavaScript实现开关等效果
2017/09/08 Javascript
js装饰设计模式学习心得
2018/02/17 Javascript
react中fetch之cors跨域请求的实现方法
2018/03/14 Javascript
vue内置指令详解
2018/04/03 Javascript
vue--点击当前增加class,其他删除class的方法
2018/09/15 Javascript
详解VUE单页应用骨架屏方案
2019/01/17 Javascript
通过Nodejs搭建网站简单实现注册登录流程
2019/06/14 NodeJs
基于javascript的无缝滚动动画实现2
2020/08/07 Javascript
vue开发chrome插件,实现获取界面数据和保存到数据库功能
2020/12/01 Vue.js
MySQLdb ImportError: libmysqlclient.so.18解决方法
2014/08/21 Python
Django 连接sql server数据库的方法
2018/06/30 Python
Python3 单行多行万能正则匹配方法
2019/01/07 Python
如何设置PyCharm中的Python代码模版(推荐)
2020/11/20 Python
Matplotlib中rcParams使用方法
2021/01/05 Python
css3 column实现卡片瀑布流布局的示例代码
2018/06/22 HTML / CSS
联想瑞士官方网站:Lenovo Switzerland
2017/11/19 全球购物
如何在存储过程中使用Loop
2016/01/05 面试题
分厂厂长岗位职责
2013/12/29 职场文书
餐厅筹备计划书
2014/04/25 职场文书
蟋蟀的住宅教学反思
2014/04/26 职场文书
新书发布会策划方案
2014/06/09 职场文书
欢迎横幅标语
2014/06/17 职场文书
大学生迟到检讨书500字
2014/10/17 职场文书
优秀班主任材料
2014/12/16 职场文书
个人落户申请书怎么写?
2019/06/28 职场文书
详解Java实践之抽象工厂模式
2021/06/18 Java/Android