contextlib

在Python中操作文件可以使用try...finallytry...finally非常繁琐。Python的with语句允许我们非常方便地使用资源,而不必担心资源没有关闭

with open('/path/to/file', 'r') as f:
    f.read()

并不是只有open()函数返回的fp对象才能使用with语句。实际上,任何对象,只要正确实现了上下文管理,就可以用于with语句。

实现上下文管理是通过__enter____exit__这两个方法实现的。例如,下面的class实现了这两个方法

class Query:
    def __init__(self,name):
        self.name = name

    def __enter__(self):
        print('Begin')
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            print('Error')
        else:
            print('End')

    def query(self):
        print('Query info about %s ... ' % self.name)


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')


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