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聚类算法之凝聚层次聚类实例分析
Nov 20 Python
Java Web开发过程中登陆模块的验证码的实现方式总结
May 25 Python
Python实现的栈(Stack)
Jan 26 Python
使用python和pygame绘制繁花曲线的方法
Feb 24 Python
python requests 测试代理ip是否生效
Jul 25 Python
对python opencv 添加文字 cv2.putText 的各参数介绍
Dec 05 Python
python 实现绘制整齐的表格
Nov 18 Python
python 实现Flask中返回图片流给前端展示
Jan 09 Python
pytorch方法测试——激活函数(ReLU)详解
Jan 15 Python
vscode配置anaconda3的方法步骤
Aug 08 Python
属性与 @property 方法让你的python更高效
Sep 21 Python
Python从文件中读取数据的方法步骤
Nov 18 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
PHP 和 MySQL 基础教程(三)
2006/10/09 PHP
php中实现可以返回多个值的函数实例
2015/03/21 PHP
DEDECMS首页调用图片集里的多张图片
2015/06/05 PHP
jQuery+Ajax+PHP“喜欢”评级功能实现代码
2015/10/08 PHP
PHP Trait代码复用类与多继承实现方法详解
2019/06/17 PHP
对象的类型:本地对象(1)
2006/12/29 Javascript
JavaScript 全角转半角部分
2009/10/28 Javascript
jquery隐藏标签和显示标签的实例
2013/11/11 Javascript
使用JavaScript 编写简单计算器
2014/11/24 Javascript
JavaScript实现在页面间传值的方法
2015/04/07 Javascript
JQuery限制复选框checkbox可选中个数的方法
2015/04/20 Javascript
使用jQuery.form.js/springmvc框架实现文件上传功能
2016/05/12 Javascript
在Mac OS上安装使用Node.js的项目自动化构建工具Gulp
2016/06/18 Javascript
AngularJS基础 ng-disabled 指令详解及简单示例
2016/08/01 Javascript
Angular.js实现动态加载组件详解
2017/05/28 Javascript
jquery+css3实现熊猫tv导航代码分享
2018/02/12 jQuery
浅谈开发eslint规则
2018/10/01 Javascript
详解项目升级到vue-cli3的正确姿势
2019/01/28 Javascript
Nodejs实现微信分账的示例代码
2021/01/19 NodeJs
详解Django框架中用context来解析模板的方法
2015/07/20 Python
5种Python单例模式的实现方式
2016/01/14 Python
Python爬取个人微信朋友信息操作示例
2018/08/03 Python
python搜索包的路径的实现方法
2019/07/19 Python
Python中调用其他程序的方式详解
2019/08/06 Python
详解pandas中iloc, loc和ix的区别和联系
2020/03/09 Python
使用Python封装excel操作指南
2021/01/29 Python
Pytorch模型迁移和迁移学习,导入部分模型参数的操作
2021/03/03 Python
HTML5 3D旋转相册的实现示例
2019/12/03 HTML / CSS
美国专注于健康商品的网站:eVitamins
2017/01/23 全球购物
英国户外装备和冒险服装零售商:alloutdoor
2018/01/30 全球购物
澳大利亚购买健身器材网站:Gym Direct
2019/12/19 全球购物
锦旗标语大全
2014/06/23 职场文书
婚姻出轨保证书
2015/05/08 职场文书
golang 实现对Map进行键值自定义排序
2021/04/28 Golang
css position fixed 左右双定位的实现代码
2021/04/29 HTML / CSS
常用的MongoDB查询语句的示例代码
2021/07/25 MongoDB