[关闭]
@spiritnotes 2016-05-24T02:39:50.000000Z 字数 1100 阅读 1550

Python语言实践分析 -- with语句

Python


概述

使用C++的人往往对其中的资源释放即析构由很深的印象,其本质是将资源的释放与变量的析构函数相结合,利用语言保证的析构函数的执行的确定性来进行资源清理。在Python中有与之类似的一种机制,即是With语句。
With语句作用于上下文管理器对象中,其使用方法如下:

  1. with open('temp','w') as f:
  2. f.write('a') #针对f进行操作
  3. f.write('b')

结果:

  1. Traceback (most recent call last):
  2. ......
  3. f.write('b')
  4. ValueError: I/O operation on closed file.

原理

  1. with <表达式> [as <变量名>]:
  2. <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__方法即可。

  1. class TestContext(object):
  2. def __exit__(self, exception_type, exception_value, traceback):
  3. print('exit')
  4. return True
  5. def __enter__(self):
  6. print('enter')
  7. with TestContext():
  8. print('...')

结果:

  1. enter
  2. ...
  3. exit

嵌套

With支持同时多个上下文管理器对象,其实质与嵌套With语句相似。

  1. with exp1 as a, exp2 as b:
  2. pass
  3. # 相当于
  4. with exp1 as a:
  5. with exp2 as b:
  6. pass

contextlib

标准库中有contextlib模块,其可以通过yield实现上下文管理器对象。

  1. import contextlib
  2. @contextlib.contextmanager
  3. def work():
  4. print('First part!')
  5. yield
  6. print('last part!')
  7. with work():
  8. print('middle part')

closing

nest

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注