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的gevent框架的入门教程
Apr 29 Python
Python彩色化Linux的命令行终端界面的代码实例分享
Jul 02 Python
python使用正则表达式替换匹配成功的组并输出替换的次数
Nov 22 Python
Python实现的rsa加密算法详解
Jan 24 Python
pyqt5 禁止窗口最大化和禁止窗口拉伸的方法
Jun 18 Python
python cumsum函数的具体使用
Jul 29 Python
Python字典常见操作实例小结【定义、添加、删除、遍历】
Oct 25 Python
python3 常见解密加密算法实例分析【base64、MD5等】
Dec 19 Python
使用Python将图片转正方形的两种方法实例代码详解
Apr 29 Python
详解Pycharm第三方库的安装及使用方法
Dec 29 Python
python编程的核心知识点总结
Feb 08 Python
Python爬虫进阶之Beautiful Soup库详解
Apr 29 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
解析数组非数字键名引号的必要性
2013/08/09 PHP
JS清除IE浏览器缓存的方法
2013/07/26 Javascript
在百度知道团队中快速审批新成员的js脚本
2014/02/02 Javascript
js设置文本框中焦点位置在最后的示例代码(简单实用)
2014/03/04 Javascript
jQuery内置的AJAX功能和JSON的使用实例
2014/07/27 Javascript
Angularjs 滚动加载更多数据
2016/03/17 Javascript
Bootstrap Validator 表单验证
2016/07/25 Javascript
JS函数修改html的元素内容,及修改属性内容的方法
2016/10/28 Javascript
概述如何实现一个简单的浏览器端js模块加载器
2016/12/07 Javascript
Es6 写的文件import 起来解决方案详解
2016/12/13 Javascript
Javascript for in的缺陷总结
2017/02/03 Javascript
Bootstrap下拉菜单样式
2017/02/07 Javascript
利用vue.js插入dom节点的方法
2017/03/15 Javascript
详解angularjs 学习之 scope作用域
2018/01/15 Javascript
基于Vue实现关键词实时搜索高亮显示关键词
2018/07/21 Javascript
javascript异步处理与Jquery deferred对象用法总结
2019/06/04 jQuery
vue+ElementUI 关闭对话框清空验证,清除form表单的操作
2020/08/06 Javascript
分享8个JavaScript库可更好地处理本地存储
2020/10/12 Javascript
vue中activated的用法
2021/01/03 Vue.js
使用python提取html文件中的特定数据的实现代码
2013/03/24 Python
python k-近邻算法实例分享
2014/06/11 Python
Python算法之栈(stack)的实现
2014/08/18 Python
python使用fcntl模块实现程序加锁功能示例
2017/06/23 Python
django基础学习之send_mail功能
2019/08/07 Python
解决Jupyter notebook更换主题工具栏被隐藏及添加目录生成插件问题
2020/04/20 Python
python xlsxwriter模块的使用
2020/12/24 Python
css3实现简单的白云飘动背景特效
2020/10/28 HTML / CSS
英国最红的高街时尚品牌:Topshop
2016/08/05 全球购物
Shop Apotheke瑞士:您的健康与美容网上商店
2019/10/09 全球购物
大型活动策划方案
2014/01/12 职场文书
医药销售求职信范文
2014/02/01 职场文书
重阳节演讲稿:尊敬帮助老人 弘扬传统美德
2014/09/25 职场文书
学前班幼儿评语大全
2014/12/29 职场文书
鲁迅故居导游词
2015/02/05 职场文书
Java中try catch处理异常示例
2021/12/06 Java/Android
Nginx设置HTTPS的方法步骤 443证书配置方法
2022/03/21 Servers