python迭代器面试题_Python面试题:with的用法与自我实现

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值