contextlib 上下文管理器
在Python中,读写文件这样的资源要特别注意,必须在使用完毕后正确关闭它们。正确关闭文件资源的一个方法是使用try...finally:
try:
f = open('/path/to/file', 'r')
f.read()
finally:
if f:
f.close()
写try...finally非常繁琐。Python的with语句允许我们非常方便地使用资源,而不必担心资源没有关闭,所以上面的代码可以简化为:
with open('/path/to/file', '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这个decorator接受一个generator,用yield语句把with ... as var把变量输出出去,然后,with语句就可以正常地工作了:
with create_query('Bob') as q:
q.query()
很多时候,我们希望在某段代码执行前后自动执行特定代码,也可以用@contextmanager实现。例如:
@contextmanager
def tag(name):
print("<%s>" % name)
yield
print("</%s>" % name)
with tag("h1"):
print("hello")
print("world")
上述代码执行结果为:
<h1>
hello
world
</h1>
代码的执行顺序是:
with语句首先执行yield之前的语句,因此打印出<h1>;yield调用会执行with语句内部的所有语句,因此打印出hello和world;- 最后执行
yield之后的语句,打印出</h1>。
因此,@contextmanager让我们通过编写generator来简化上下文管理。
@closing
如果一个对象没有实现上下文,我们就不能把它用于with语句。这个时候,可以用closing()来把该对象变为上下文对象。例如,用with语句使用urlopen():
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,这个generator编写起来其实非常简单:
@contextmanager
def closing(thing):
try:
yield thing
finally:
thing.close()
它的作用就是把任意对象变为上下文对象,并支持with语句。
@contextlib还有一些其他decorator,便于我们编写更简洁的代码。
contextlib 上下文管理器的更多相关文章
- python contextlib 上下文管理器
1.with操作符 在python中读写文件,可能需要这样的代码 try-finally读写文件 file_text = None try: file_text = open('./text', 'r ...
- (转)contextlib — 上下文管理器工具
原文:https://pythoncaff.com/docs/pymotw/contextlib-context-manager-tool/95 这是一篇社区协同翻译的文章,你可以点击右边区块信息里的 ...
- 【Python】 上下文管理器和contextlib
上下文管理器 一直对python中的上下文管理比较迷惑,趁着今天研究SQLAlchemy顺便看了一下,感觉稍微清楚了一点.http://www.cnblogs.com/chenny7/p/421344 ...
- python上下文管理器ContextLib及with语句
http://blog.csdn.net/pipisorry/article/details/50444736 with语句 with语句是从 Python 2.5 开始引入的一种与异常处理相关的功能 ...
- python 上下文管理器contextlib.ContextManager
1 模块简介 在数年前,Python 2.5 加入了一个非常特殊的关键字,就是with.with语句允许开发者创建上下文管理器.什么是上下文管理器?上下文管理器就是允许你可以自动地开始和结束一些事情. ...
- Python中的上下文管理器(contextlib模块)
上下文管理器的任务是:代码块执行前准备,代码块执行后收拾 1 如何使用上下文管理器: 打开一个文件,并写入"hello world" filename="my.txt&q ...
- Python 上下文管理器模块--contextlib
在 Python 处理文件的时候我们使用 with 关键词来进行文件的资源关闭,但是并不是只有文件操作才能使用 with 语句.今天就让我们一起学习 Python 中的上下文管理 contextlib ...
- contextlib:上下文管理器工具
介绍 contextlib模块包含的工具可以用于处理上下文管理器和with语句 上下文管理器API ''' 上下文管理器(context manager)负责管理一个代码块中的资源,会在进入代码块时创 ...
- python2.7高级编程 笔记一(Python中的with语句与上下文管理器学习总结)
0.关于上下文管理器上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象. with manager as var: do_something(var) 相当于以 ...
随机推荐
- 销售人员的分析,也可以用类似RFM的思路吗?
本文转自知乎 作者:接地气的陈老师 ————————————————————————————————————————————————————— 有同学问:“销售人员的分析,也可以用类似RFM的思路吗, ...
- dubbo 学习资料
入门: http://www.tuicool.com/articles/FnE3em http://www.cnblogs.com/xuyatao/p/6869231.html 最好 http://w ...
- GPUImage中亮度调整的实现——GPUImageBrightnessFilter
亮度brightness其实是对RGB的调整,RGB值越大,效果越亮:反之则越暗. GPUImage中提供了对图像亮度调整的Filter,其核心代码如下(fragment): varying high ...
- markdown的试用
因为markdown,我接触到latex,因为latex,我花了几个月去看相关的书籍 我看了以下相关的资料 1.<LaTeX入门> 刘海洋 2.英文 TeX - LaTeX Stack E ...
- python linux 下开发环境搭建
1.1: 在虚拟环境目录下安装 ipython => pip install ipython 1.2: 简单的使用 => ipthyon => print("heollo ...
- ThinkCentre进入BIOS,设置intel virtualization technology
VMware安装提示cpu虚拟化intel virtualization technology ThinkCentre重启长按F1 按enter,开启intel virtualization tech ...
- leetcode1021
class Solution(object): def removeOuterParentheses(self, S: str) -> str: li = list() bcode = 0 te ...
- 09-清除默认格式 reset.css
根据需要选择和裁剪后使用,以减少代码量 /* 清除内外边距 */ body, h1, h2, h3, h4, h5, h6, hr, p, blockquote, /* structural elem ...
- hexo发表博文
3.4创建博客文章与发布 在hexo 目录下终端命令: $ hexo new '文件名' //会在source/_posts创建一个文件名.md文件 这就可以使用markdown编辑器开始写自己的博客 ...
- TMG2010安装配置细节设定
TMG2010最适合的操作系统是Win2008R2,不支持Win2012,可能是因为发布Win2012系统时,微软已经决定废弃TMG改为支持UAG了吧. 在Win2012下安装TMG2010,运行TM ...