python语言使用什么语句实现上下文管理协议_8.python之上下文管理协议

使用上下文管理协议,有什么好处?使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预。

在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在__exit__中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处。

之前所提到的with代码块,就是python的上下文管理操作,比如说通过python打开一个文件,就可以通过with代码块结合open去实现,通过这种方式打开的文件,执行了相应的操作后,无需我们手动去close文件,文件就会自动关闭。

比如:

with open('a.txt') as f:

'代码块'

#上面这个例子,就是一个上下文管理协议,即with语句,为了让一个对象可以去兼容with语句,则必须在这个对象的类中,去声明__enter__和__exit__方法。

这种上下文的管理,就是通过类中的__enter__和__exit__这两个内置方法去实现的。

下面是__enter__和__exit__的用法示例:

class test:

def __init__(self,name):

self.name = name

def __enter__(self):

#print "只要with语句一出现,这个对象的__enter__方法就会被触发,__enter__这个方法的返回值会赋值给as 后面声明的变量"

print "我是__enter__方法,with出现时就会执行我~"

def __exit__(self, exc_type, exc_val, exc_tb):

print "我是__exit__方法,__enter__执行完毕会执行我"

with test(123) as t1:

print "aaaa"

我们来看看输出结果:

我是__enter__方法,with出现时就会执行我~

aaaa

我是__exit__方法,__enter__执行完毕会执行我

#__exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行。

#传入__exit__方法中的exc_type,exc_val,exc_tb,分别是(异常类,异常的值,追踪信息)这三个参数只有当__enter__方法或者with下的代码块下的代码出现异常,这三个参数才会有值,否则就是三个None。

#__exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则with后的代码都无法执行,直接开始执行__exit__方法。

关于上下文管理的异常处理:

class Open:

def __init__(self,name):

self.name=name

def __enter__(self):

print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')

def __exit__(self, exc_type, exc_val, exc_tb):

print('with中代码块执行完毕时执行我啊')

print(exc_type)

print(exc_val)

print(exc_tb)

with Open('a.txt') as f:

print('=====>执行代码块')

raise AttributeError('***着火啦,救火啊***')

print('0'*100) #------------------------------->不会执行

从上面这个例子可以看出来,当with的代码块的执行出现异常的时候,python会直接开始执行对象的__exit__方法,当__exit__内的方法也执行完毕,整个程序就终止掉了。

那么,如何处理with代码块中的异常呢?

注意看下面这个例子!!

class Open:

def __init__(self,name):

self.name=name

def __enter__(self):

print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')

def __exit__(self, exc_type, exc_val, exc_tb):

print('with中代码块执行完毕时执行我啊')

print(exc_type)

print(exc_val)

print(exc_tb)

return True        #注意这里!!!!

with Open('a.txt') as f:

print('=====>执行代码块')

raise AttributeError('***着火啦,救火啊***')

print('0'*100) #------------------------------->会执行

当__exit__方法,返回的为值True时,就好像啥都没发生一样,with后的语句正常执行,with代码块中的异常被屏蔽掉了!!

最后关于python的上下文管理,做一个总结:在没有任何异常的情况下,整个代码块的内容运行完毕后会去触发对象的__exit__方法,它的三个参数都为None。

当有异常存在的情况下,从异常位置,直接触发__exit__。

2.1 当手动将__exit__方法的返回值修改为True,with语句就会屏蔽掉异常。

2.2 当__exit__的返回值不为True,在with代码块中遇到异常就会抛出。

2.3 当__exit__这个方法一旦运行完毕,就代表了整个with语句执行完毕。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值