python学习笔记- With语句的作用及其原理

python with的原理

with 语句的作用简述

with open('a','r) as f:
    for line in f:
        print line.strip()

以上代码使用with as 语句来操作一个文件,其作用为 打开一个文件,如果一切正常则,将文件对下赋值给f,然后使用迭代器遍历文件中的每一行,当最终遍历完成后,再关闭文件。且即使发生了异常,该文件仍然会被关闭。
因此with 语句的基本作用:构建对资源创建与释放的

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语句的自我实现01

通过以上的运行原理我们可以在类中自行创建 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语句的自我实现02

通过调用 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 上下文管理协议

上下文管理协议 即 enterexit

python 上下文管理器(Contextor)

上下文管理器即 实现了 上下文管理协议,当Contextor 调用/实例化时,则创建了 上下文管理器,类似实现迭代器协议类调用生成迭代器一样。

运行的执行原理:

1、执行contextor 以获取上下文管理器
2、加载上下文管理器的exit()方法,备用
3、调用上下文管理器的enter()方法
4、如果有 as 语句,则将enter() 方法的返回值赋值给 变量名
5、执行语句with 中的代码
6、调用上下文管理器的 exit() 方法,如果退出使用由于异常导致的,那么该异常的 type、value 和 traceback 会作为参数传给 exit(),否则传三个 None
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值