上下文管理器
为什么使用上下文管理器?
当我们需要申请资源(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)
- with 关键字实例化对象
- 进入init方法,打印提示,打开文件文件,实例化完成
- 进入enter方法,打印提示,返回文件对象,返回值作为赋值给f
- 文件对象f获取内容
- 打印文件内容
- 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('使用资源中...')