上下文管理器

为什么使用上下文管理器?

当我们需要申请资源(socket、句柄、锁),并且确保资源被及时释放时,可以通过使用上下文管理器完成目的

with 上下文管理器

with 关键字是最广泛的上下文管理器案例了

第一种实现方式:

with open('some_file', 'w') as opened_file:
    opened_file.write('Hola!')

第二种实现方式:

file = open('some_file', 'w')
try:
    file.write('Hola!')
finally:
    file.close()

可以看到与try finally相比,with语法更加的简洁

实现自己的上下文管理器

基于类实现

上下文管理器有两个相关的魔法函数,enter, exit

# cat context.py
class File:
    def __init__(self, file_name, method):
        print('初始化,申请资源...')
        self.file_obj = open(file_name, method)

    def __enter__(self):
        print('使用资源...')
        return self.file_obj

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        :param exc_type: 异常类型
        :param exc_val: 异常内容
        :param exc_tb:异常trackback
        :return:
        """
        print('释放资源...')
        self.file_obj.close()

if __name__ == '__main__':
    with File('/tmp/setRps.log', 'r') as f:
        content = ''.join(f.readlines())
        print(content)
  1. with 关键字实例化对象
  2. 进入init方法,打印提示,打开文件文件,实例化完成
  3. 进入enter方法,打印提示,返回文件对象,返回值作为赋值给f
  4. 文件对象f获取内容
  5. 打印文件内容
  6. with语句块中的代码执行完毕,进入exit方法,打印提示,释放文件对象

基于contextlib.contextmanager装饰器实现

from contextlib import contextmanager


@contextmanager
def open_file(file_name, method):
    # yield之前对应 __enter__
    print('初始化,申请资源...')
    f = open(file_name, method)
    yield f
    # yield之后对应__exit__
    print('释放资源...')
    f.close()


if __name__ == '__main__':
    with open_file('api.py', 'r') as f:
        content = ''.join(f.readlines())
        print('使用资源中...')

results matching ""

    No results matching ""