python基础----实现上下文管理协议__enter__和__exit__

我们知道在操作文件对象的时候可以这么写

with open('a.txt') as f:
  '代码块'

 

上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法

 1 class Open:
 2     def __init__(self,name):
 3         self.name=name
 4 
 5     def __enter__(self):
 6         print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
 7         # return self
 8     def __exit__(self, exc_type, exc_val, exc_tb):
 9         print('with中代码块执行完毕时执行我啊')
10 
11 
12 with Open('a.txt') as f:
13     print('=====>执行代码块')
14     # print(f,f.name)
15 
16 上下文管理协议
上下文管理协议

 

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

 1 class Open:
 2     def __init__(self,name):
 3         self.name=name
 4 
 5     def __enter__(self):
 6         print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
 7 
 8     def __exit__(self, exc_type, exc_val, exc_tb):
 9         print('with中代码块执行完毕时执行我啊')
10         print(exc_type)
11         print(exc_val)
12         print(exc_tb)
13 
14 
15 
16 with Open('a.txt') as f:
17     print('=====>执行代码块')
18     raise AttributeError('***着火啦,救火啊***')
19 print('0'*100) #------------------------------->不会执行
View Code

 

如果__exit()返回值为True,那么异常会被清空,就好像啥都没发生一样,with后的语句正常执行

 1 class Open:
 2     def __init__(self,name):
 3         self.name=name
 4 
 5     def __enter__(self):
 6         print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
 7 
 8     def __exit__(self, exc_type, exc_val, exc_tb):
 9         print('with中代码块执行完毕时执行我啊')
10         print(exc_type)
11         print(exc_val)
12         print(exc_tb)
13         return True
14 
15 
16 
17 with Open('a.txt') as f:
18     print('=====>执行代码块')
19     raise AttributeError('***着火啦,救火啊***')
20 print('0'*100) #------------------------------->会执行
View Code

 

用途或者说好处:

1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预

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

 -----------------------------------------------------------------------------------------------------------------

笔记:

# with open('a.txt','r') as f:
#     print('--=---->')
#     print(f.read())

# with open('a.txt', 'r'):
#     print('--=---->')


#
class Foo:
    def __enter__(self):
        print('=======================》enter')
        return 111111111111111

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('exit')
        print('exc_type',exc_type)
        print('exc_val',exc_val)
        print('exc_tb',exc_tb)
        return True


# with Foo(): #res=Foo().__enter__()
#     pass

with Foo() as obj: #res=Foo().__enter__() #obj=res
    print('with foo的自代码块',obj)
    raise NameError('名字没有定义')
    print('************************************')

print('1111111111111111111111111111111111111111')
上下文管理协议
 1 import time
 2 class Open:
 3     def __init__(self,filepath,mode='r',encode='utf-8'):
 4         self.f=open(filepath,mode=mode,encoding=encode)
 5 
 6     def write(self,line):
 7         self.f.write(line)
 8 
 9     def __getattr__(self, item):
10         return getattr(self.f,item)
11 
12     def __del__(self):
13         print('----->del')
14         self.f.close()
15 
16     def __enter__(self):
17         return self.f
18     def __exit__(self, exc_type, exc_val, exc_tb):
19         self.f.close()
20 
21 
22 with Open('egon.txt','w') as f:
23     f.write('egontest\n')
24     f.write('egontest\n')
25     f.write('egontest\n')
26     f.write('egontest\n')
27     f.write('egontest\n')
28 
29 
30 
31 
32 
33 
34 
35 class Open:
36     def __init__(self,filepath,mode,encode='utf-8'):
37         self.f=open(filepath,mode=mode,encoding=encode)
38         self.filepath=filepath
39         self.mode=mode
40         self.encoding=encode
41 
42     def write(self,line):
43         print('write')
44         self.f.write(line)
45 
46     def __getattr__(self, item):
47         return getattr(self.f,item)
48 
49     def __enter__(self):
50         return self
51 
52     def __exit__(self, exc_type, exc_val, exc_tb):
53         self.f.close()
54         return True
55 
56 with Open('aaaaa.txt','w') as write_file: #write_file=Open('aaaaa.txt','w')
57     write_file.write('123123123123123\n')
58     write_file.write('123123123123123\n')
59     print(sssssssssssssss)
60     write_file.write('123123123123123\n')
上下文管理协议01

 

posted @ 2017-04-25 16:32  ForeverPine  阅读(634)  评论(0编辑  收藏  举报
TOP