@spiritnotes
2016-05-24T02:39:50.000000Z
字数 1100
阅读 1904
Python
使用C++的人往往对其中的资源释放即析构由很深的印象,其本质是将资源的释放与变量的析构函数相结合,利用语言保证的析构函数的执行的确定性来进行资源清理。在Python中有与之类似的一种机制,即是With语句。
With语句作用于上下文管理器对象中,其使用方法如下:
with open('temp','w') as f:f.write('a') #针对f进行操作f.write('b')
结果:
Traceback (most recent call last):......f.write('b')ValueError: I/O operation on closed file.
with <表达式> [as <变量名>]:<with语句块>
With语句语法如上,其执行过程如下:
1. 执行表达式,返回一个上下文管理器对象
2. 加载上下文管理对象的__exit__方法供后面使用
3. 调用上下文管理对象的__enter__方法
4. 如设置目标对象,将返回值赋值给目标对象
5. 执行with块中的代码块
6. 正常结束,使用None参数调用__exit__方法
7. 异常结束,则调用__exit__(exception_type, exception_value, traceback),如果__exit__返回true,则往下继续执行,如__exit__返回false,则异常重新抛出
因此如果需要自己实现上下文管理器对象,只需要实现__exit__和__enter__方法即可。
class TestContext(object):def __exit__(self, exception_type, exception_value, traceback):print('exit')return Truedef __enter__(self):print('enter')with TestContext():print('...')
结果:
enter...exit
With支持同时多个上下文管理器对象,其实质与嵌套With语句相似。
with exp1 as a, exp2 as b:pass# 相当于with exp1 as a:with exp2 as b:pass
标准库中有contextlib模块,其可以通过yield实现上下文管理器对象。
import contextlib@contextlib.contextmanagerdef work():print('First part!')yieldprint('last part!')with work():print('middle part')
