跳转至

contextlib

上下文管理器

参见上下文管理器

@contextmanager

编写__enter__()__exit__()非常繁琐, 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')
    o = Query(name)
    yield o
    print('End')

with create_query('example') as q:
    q.query()

执行:

$ python main.py
Begin
Query info about example...
End

执行过程:

  1. with语句首先调用create_query()函数, 打印'Begin', 创建对象o, 通过yield返回创建的对象o, with语句将其赋值给q
  2. 执行with语句内部的代码块, 即执行q.query()方法, 打印'Query info about example...'
  3. 执行完成后, 继续执行create_query()yield语句之后的代码, 打印'End'

定义:

from contextlib import contextmanager

@contextmanager
def tag(name):
    print("<%s>" % name)
    yield
    print("</%s>" % name)

with tag("h1"):
    print("hello")
    print("world")

执行:

$ python main.py
<h1>
hello
world
</h1>

@closing

@closing装饰器的主要作用是将一个未实现上下文的对象作用于上下文管理器, 其中实现了with语句块执行完成后自动执行[obj].close()的功能.

例子
from contextlib import closing
from urllib.request import urlopen

with closing(urlopen('https://www.python.org')) as page:
    for line in page:
        print(line)
Tip

其实@closing是一个经过@contextmanager装饰的生成器, 具体实现如下:

@contextmanager
def closing(thing):
    try:
        yield thing
    finally:
        thing.close()

  1. Contextlib. (n.d.). Retrieved June 19, 2024, from https://www.liaoxuefeng.com/wiki/1016959663602400/1115615597164000