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版
Dec 07 Python
Python实现向QQ群成员自动发邮件的方法
Nov 19 Python
Python Sleep休眠函数使用简单实例
Feb 02 Python
python实现堆和索引堆的代码示例
Mar 19 Python
python删除某个字符
Mar 19 Python
python变量赋值方法(可变与不可变)
Jan 12 Python
python 实现创建文件夹和创建日志文件的方法
Jul 07 Python
python模拟键盘输入 切换键盘布局过程解析
Aug 15 Python
python飞机大战 pygame游戏创建快速入门详解
Dec 17 Python
selenium中get_cookies()和add_cookie()的用法详解
Jan 06 Python
Python count函数使用方法实例解析
Mar 23 Python
python Scrapy爬虫框架的使用
Jan 21 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
js获取浏览器的可视区域尺寸的实现代码
2011/11/30 Javascript
js文本框输入点回车触发确定兼容IE、FF等
2013/11/19 Javascript
Jquery 过滤器(first,last,not,even,odd)的使用
2014/01/22 Javascript
在JavaScript中构建ArrayList示例代码
2014/09/17 Javascript
jQuery+slidereveal实现的面板滑动侧边展出效果
2015/03/14 Javascript
jQuery获取file控件中图片的宽高与大小
2016/08/04 Javascript
js实现无缝滚动图(可控制当前滚动的方向)
2017/02/22 Javascript
Js实现中国公民身份证号码有效性验证实例代码
2017/05/03 Javascript
微信小程序 支付功能实现PHP实例详解
2017/05/12 Javascript
小程序如何使用分包加载的实现方法
2019/05/22 Javascript
对layui中table组件工具栏的使用详解
2019/09/19 Javascript
JavaScript中如何对多维数组(矩阵)去重的实现
2019/12/04 Javascript
[07:49]2014DOTA2国际邀请赛 Newbee夺冠后采访xiao8坦言奖金会上交
2014/07/23 DOTA
[42:25]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第三场
2018/04/06 DOTA
python二叉树遍历的实现方法
2013/11/21 Python
Python实现建立SSH连接的方法
2015/06/03 Python
Python实现PS图像明亮度调整效果示例
2018/01/23 Python
python单例模式获取IP代理的方法详解
2018/09/13 Python
python找出完数的方法
2018/11/12 Python
浅谈python脚本设置运行参数的方法
2018/12/03 Python
利用Python如何制作贪吃蛇及AI版贪吃蛇详解
2020/08/24 Python
python与js主要区别点总结
2020/09/13 Python
CSS3条纹背景制作的实战攻略
2016/05/31 HTML / CSS
HTML5 实战PHP之Web页面表单设计
2011/10/09 HTML / CSS
Unix如何添加新的用户
2014/08/20 面试题
自荐信格式技巧有哪些呢
2013/11/19 职场文书
《乌鸦和狐狸》教学反思
2014/02/08 职场文书
舞蹈毕业生的自我评价
2014/03/05 职场文书
数控专业自荐书范文
2014/03/16 职场文书
2014年入党积极分子学习三中全会思想汇报
2014/09/13 职场文书
代领报检证委托书范本
2014/10/11 职场文书
2015年教师自我评价范文
2015/03/04 职场文书
工作犯错保证书
2015/05/11 职场文书
心灵捕手观后感
2015/06/02 职场文书
2016大学生毕业实习心得体会
2016/01/23 职场文书
JavaCV实现照片马赛克效果
2022/01/22 Java/Android