@spiritnotes
2016-05-24T02:39:50.000000Z
字数 1100
阅读 1701
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 True
def __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.contextmanager
def work():
print('First part!')
yield
print('last part!')
with work():
print('middle part')