with 语句的作用
with 语句的基本作用:构建对资源创建与释放的with open('a','r) as f:
for line in f:
print line.strip()
以上代码使用with as 语句来操作一个文件,其作用为 打开一个文件,如果一切正常则,将文件对下赋值给f,然后使用迭代器遍历文件中的每一行,当最终遍历完成后,再关闭文件。且即使发生了异常,该文件仍然会被关闭。
with执行原理
当with 执行时,执行 上下文表达式(context_expr) 来获得一个上下文管理器,上下文管理器的职责是提供一个上下文对象,用于在with语句块中处理细节:
1、 一旦获取的上下文对象,就会调用它的 enter() 方法,将完成 with语句 块执行前的所有准备功能工作。
2、如果with 语句后面跟了 as 语句,则用 enter() 方法的返回值来赋值;
3、当with语句块结束时,无论是正常结束,还是由于异常,都会调用上下文对象的__exit__()方法,exit()方法有3个参数,如果with语句正常结束,三个参数全部都是 None;如果发生异常,三个参数的值分别等于调用sys.exc_info()函数返回的三个值:类型(异常类)、值(异常实例)和跟踪记录(traceback),相应的跟踪记录对象。
with支持对象
通过以上的原理可以知道,我们不能对任意的python 对象都使用 with 语句, 对象需要支持 上下文管理协议。
也就是说,只有内建了“上下文管理”的对象可以和with一起工作,目前支持该协议的对象有:file
decimal.Context
thread.LockType
threading.Lock
threading.RLock
threading.Condition
threading.Semaphore
threading.BoundedSemaphore
with语句的自我实现
通过以上的运行原理可知,我们可以在类中自行创建 enter() 和 exit() 方法,来配合 with 语句创建类实例:class Test:
def __enter__(self):
print 'begin connect ...'
def __exit__(self,exc_type, exc_val, exc_tb):
print 'close connect...'
if __name__ == '__main__':
with Test() as f:
print 'run...'
with语句的自我实现
通过调用 python 的 contextlib 模块,可以不需要构造含有 enter,exit 的类就可以使用with, 注意需结合yield 使用 (目前仅知道该用法)from contextlib import contextmanager
@contextmanager
def test():
print 'begin connect ...'
yield 'ddd'
print 'close connect...'
if __name__ == '__main__':
#未赋值,则不输出函数中的返回值
with test():
print 'a'
#赋值,输出函数中的返回值
with test() as f:
print f
print 'a'
python 上下文管理协议
上下文管理协议 即 enter 和 exit
python 上下文管理器(Contextor)
上下文管理器即 实现了 上下文管理协议,当Contextor 调用/实例化时,则创建了 上下文管理器,类似实现迭代器协议类调用生成迭代器一样。运行的执行原理:
1、执行contextor 以获取上下文管理器
2、加载上下文管理器的exit()方法,备用
3、调用上下文管理器的enter()方法
4、如果有 as 语句,则将enter() 方法的返回值赋值给 变量名
5、执行语句with 中的代码
6、调用上下文管理器的 exit() 方法,如果退出使用由于异常导致的,那么该异常的 type、value 和 traceback 会作为参数传给 exit(),否则传三个 None