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保存字符串到文件的方法
Jul 01 Python
python套接字流重定向实例汇总
Mar 03 Python
Python MySQL数据库连接池组件pymysqlpool详解
Jul 07 Python
Python内置函数 next的具体使用方法
Nov 24 Python
Django框架实现的分页demo示例
May 25 Python
Python正则表达式匹配数字和小数的方法
Jul 03 Python
python防止随意修改类属性的实现方法
Aug 21 Python
双向RNN:bidirectional_dynamic_rnn()函数的使用详解
Jan 20 Python
浅谈python出错时traceback的解读
Jul 15 Python
如何利用Python 进行边缘检测
Oct 14 Python
Python学习之异常中的finally使用详解
Mar 16 Python
Python 操作pdf pdfplumber读取PDF写入Exce
Aug 14 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实现parent调用父类的构造方法与被覆写的方法
2015/02/11 PHP
PHP中实现Bloom Filter算法
2015/03/30 PHP
PHP判断表达式中括号是否匹配的简单实例
2016/10/22 PHP
PDO::commit讲解
2019/01/27 PHP
微信公众号实现扫码获取微信用户信息(网页授权)
2019/04/09 PHP
JQuery UI的拖拽功能实现方法小结
2012/03/14 Javascript
Extjs中使用extend(js继承) 的代码
2012/03/15 Javascript
为EasyUI的Tab标签添加右键菜单的方法
2012/07/14 Javascript
基于JQuery的一句话搞定手风琴菜单
2012/09/14 Javascript
JS对HTML标签select的获取、添加、删除操作
2013/10/17 Javascript
JS复制到剪贴板示例代码
2013/10/30 Javascript
js加入收藏以及使用Jquery更改透明度
2014/01/26 Javascript
jQuery Easyui 验证两次密码输入是否相等
2016/05/13 Javascript
早该知道的7个JavaScript技巧
2016/06/21 Javascript
简单实现js页面切换功能
2021/01/10 Javascript
Vue 过渡实现轮播图效果
2017/03/27 Javascript
初识NodeJS服务端开发入门(Express+MySQL)
2017/04/07 NodeJs
浅谈AngularJS中使用$resource(已更新)
2017/09/14 Javascript
使用JS实现气泡跟随鼠标移动的动画效果
2017/09/16 Javascript
Angular实现类似博客评论的递归显示及获取回复评论的数据
2017/11/06 Javascript
NodeJs实现定时任务的示例代码
2017/12/05 NodeJs
基于jquery实现左右上下移动效果
2018/05/02 jQuery
JS JQuery获取data-*属性值方法解析
2020/09/01 jQuery
实例讲解Python编程中@property装饰器的用法
2016/06/20 Python
python snownlp情感分析简易demo(分享)
2017/06/04 Python
解决python3读取Python2存储的pickle文件问题
2018/10/25 Python
Python面向对象之类和实例用法分析
2019/06/08 Python
CSS3教程(7):CSS3嵌入字体
2009/04/02 HTML / CSS
HTML5上传文件显示进度的实现代码
2012/08/30 HTML / CSS
html5声频audio和视频video等新特性详细说明
2012/12/26 HTML / CSS
瑞贝卡·泰勒官方网站:Rebecca Taylor
2016/09/24 全球购物
汉语专业应届生求职信
2013/10/01 职场文书
党员学习党的群众路线思想汇报(5篇)
2014/09/10 职场文书
《穷人》教学反思
2016/02/19 职场文书
Python超简单容易上手的画图工具库推荐
2021/05/10 Python
MySQL子查询中order by不生效问题的解决方法
2021/08/02 MySQL