contextlib是一个Python模块,作用是提供更易用的上下文管理器。
编写 __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) @contextmanagerdef 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()
代码的执行顺序是:
- with 语句 首先执行 yield 之前的语句,因此打印出 <h1>.
- yield 调用会执行 with 语句内部的所有语句,因此打印出 hello 和 world.
- 最后执行yield之后的语句,打印出 </h1>.
如果一个对象没有实现上下文,就不能使用 with 语句,但是可以用 closing() 来把对象变为上下文对象。
1 2 3 4 5 6 | 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
1 2 3 4 5 6 | @contextmanager def closing(thing): try : yield thing finally : thing.close() |
它的作用就是把任意对象变为上下文对象,并支持 with语句。
@contextmanager 这个装饰器接受一个 generator,用 yield 语句把 with ... as var 把变量输出出去,然后,with 语句就可以正常的工作了:
1 2 | with create_query( 'Bob' ) as q: q.query() |