python中的with语句_python之with语句

一、情景再现

在Python中,我们在打开文件的时候,为了代码的健壮性,通常要考虑一些异常情况,比如:

try:

ccfile= open('/path/data')

content=ccfile.readlines()

ccfile.close()exceptIOError:

log.write('no data read\n')

如果文件操作出现异常,则写一条错误日志;

考虑一种情况,如果文件打开成功,但readlines()调用失败,异常处理会立即跳转到except处执行,这样文件关闭就没有机会被执行到了。

一种解决办法就是将close()语句放到finally子句中去,finally的特点是不管有无异常,都会被执行到。

try:try:

ccfile= open('/path/data')

content=ccfile.readlines()exceptIOError:

log.write('no data read\n')finallyccfile.close()

try:try:

ccfile= open('/path/data')

content=ccfile.readlines()finallyIOError:

ccfile.close()exceptIOError:

log.write('no data read\n')

但是上面的语句很不优雅。可以使用with语句:

with open('/etc/passwd') as f:for line inf:print(line)

二、with语句

1、with语句仅仅能对支持上下文管理协议的对象使用。支持本协议的对象

file

decimal.Context

thread.LockType

threading.Lock

threading.RLock

threading.Condition

threading.Semaphore

threading.BoundedSemaphore

2、with语句执行的解析:

with context_expr() as var:

doSomething()

当with语句执行时,便执行上下文表达式(context_expr)(一般为某个方法)来获得一个上下文管理器对象,上下文管理器的职责是提供一个上下文对象,用于在with语句块中处理细节:

一旦获得了上下文对象,就会调用它的__enter__()方法,将完成with语句块执行前的所有准备工作,如果with语句后面跟了as语句,则用__enter__()方法的返回值来赋值;

当with语句块结束时,无论是正常结束,还是由于异常,都会调用上下文对象的__exit__()方法,__exit__()方法有3个参数,如果with语句正常结束,三个参数全部都是 None;如果发生异常,三个参数的值分别等于调用sys.exc_info()函数返回的三个值:类型(异常类)、值(异常实例)和跟踪记录(traceback),相应的跟踪记录对象。

因为上下文管理器主要作用于共享资源,__enter__()和__exit__()方法基本是完成的是分配和释放资源的低层次工作,比如:数据库连接、锁分配、信号量加/减、状态管理、文件打开/关闭、异常处理等。

3、自定义类使用with来管理

classA(object):def __enter__(self):print('__enter__() called')returnselfdefprint_hello(self):print("hello world!")def __exit__(self, e_t, e_v, t_b):print('__exit__() called')#首先会执行__enter__方法

with A() as a: #a为__enter__的返回对象

a.print_hello()print('got instance')#结束会执行__exit__方法

输出结果:

__enter__() called

hello world!

got instance__exit__() called

三、contextlib模块实现上下文自动管理

@contextmanagerdefcontext():print('entering the zone')try:yield

exceptException as e:print('with an error %s'%e)raiseeelse:print('with no error')

with context():print('----in context call------')

输出:

entering the zone----in context call------with no error

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值