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) 相当于以 ...
随机推荐
- 34.scrapy解决爬虫翻页问题
这里主要解决的问题: 1.翻页需要找到页面中加载的两个参数. '__VIEWSTATE': '{}'.format(response.meta['data']['__VIEWSTATE']), '__ ...
- 学习笔记:ES6
http://es6.ruanyifeng.com/ ECMAScript 6 https://frankfang.github.io/es-6-tutorials/ ES 6 新特性列表 2017- ...
- 02.centos6.4找不到ifcfg-eth0(静态ip配置)
1.默认情况在/etc/sysconfig/network-scripts/目录下面找不到ifcfg-eth0文件,我们需要手动copy 1.1动态ip配置 #cp ifcfg-lo ifcfg-et ...
- 【平台兼容性】jeecg3.7 兼容weblogic 部署改造方案
MyEclipse 配置 WebLogic 10.3.3请参考: https://my.oschina.net/aini3884/blog/895689 常见问题: 1. problem: cvc-e ...
- MySQL创建只读账号
应用场景:只要公司有数据团队的,那免不了让这帮家伙把全公司的数据库数据都摸一遍,但是要是直接把root用户给了他们,未免有点危险,于是只能给这帮人设权限,一般而言,他们只是做读操作,既然做读操作,那么 ...
- 使用ubuntu远程连接windows, Connect to a Windows PC from Ubuntu via Remote Desktop Connection
from: https://www.digitalcitizen.life/connecting-windows-remote-desktop-ubuntu NOTE: This tutorial w ...
- TCP连接异常断开检测(转)
TCP是一种面向连接的协议,连接的建立和断开需要通过收发相应的分节来实现.某些时候,由于网络的故障或是一方主机的突然崩溃而另一方无法检测到,以致始终保持着不存在的连接.下面介绍一种方法来检测这种异常断 ...
- 使用exec函数将当前的信息输入到文件中
先来看看exec函数: exec函数族 fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序.当进程调用一种exec函 ...
- intellij idea 配置web 项目
Intellij Idea 创建Web项目入门(一)(转载) 相关软件: Intellij Idea14:http://pan.baidu.com/s/1nu16VyD JDK7:http://p ...
- mac+windows下从git上拉取项目及运行
一.Mac下从git拉取项目 1. 拉项目 打开终端,先进入想放置项目的目录.假设进入workfile目录,输入cd workfile. 进入workfile目录后:输入git clone 链接(gi ...