What is context manager?
A basic issue in programming is resource management: a resource is anything in limited supply, notably file handles, network sockets, locks, etc., and a key problem is making sure these are released after they are acquired. If they are not released, you have a resource leak, and the system may slow down or crash. More generally, you may want cleanup actions to always be done, other than simply releasing resources.
就像其名字一样,context manager负责管理一定的上下文环境,按照你的设定,及时分配一定的资源,在完成相应的工作之后,及时释放这些资源. 而且不止是释放资源,你还可以做其他你想的事情……
Python提供了一种特定的语法结构可以用来做如此工作,许多类型都支持context text,比如buit-in File
对象.
常用的操作
1 | with open(file_name, 'rb') as f: |
i.e.在这个例子里context manager会自动关闭f文件对象,不需要用户显示地执行代码关闭,更加安全.
仔细研究会发现,这类对象,需要实现__enter__
和__exit__
两个方法属性,上面的例子等价于
1 | f = open(file_name, 'rb') |
How to implement?
首先,通过实现__enter__
和__exit__
这两个协议方法,我们可以使用with expre [as var]:
语法来使用context manager.如:
1 | class File(object): |
__enter__
将返回值传入as
后面的var
变量,block
退出时执行__exit__
方法,更通常一些,__exit__
方法应该返回一个bool
值表示是否发生异常. 基于以上File
类的定义可以使用下面的with
statement.
1 | with File('demo.txt', 'w') as opened_file: |
处理异常也基本同理.
contextlib: Utilities for with
-statement contexts
看一下这个built-in moudulecontextlib
This module provides utilities for common tasks involving the
with
statement. For more information see also Context Manager Types and With Statement Context Managers.
contextlib.contextmanager
官方的例子是:
1 | from contextlib import contextmanager |
这个函数是个decorator函数,参考之前的一篇,它可以将函数包装为context manager,无需自己显示为其实现__enter__
和__exit__
方法.
这个函数返回一个iterator,可以使用yield
关键字
At the point where the generator yields, the block nested in the
with
statement is executed.
yield之后,便会执行块下的内容.
改写上面的例子为
1 | @contextmanager |