zoukankan      html  css  js  c++  java
  • 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
    ')
    24     f.write('egontest
    ')
    25     f.write('egontest
    ')
    26     f.write('egontest
    ')
    27     f.write('egontest
    ')
    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
    ')
    58     write_file.write('123123123123123
    ')
    59     print(sssssssssssssss)
    60     write_file.write('123123123123123
    ')
    上下文管理协议01
  • 相关阅读:
    Vue 移动端向上滑动加载
    关于NPOI 判断Office 是否为空的操作
    定时任务的处理
    Web中线程与IIS线程池自动回收机制
    本地VS调试服务器 IIS 程序
    每天学点node系列-stream
    聊聊前端模块化开发
    位运算解决多标签问题【原创】
    <未来世界的幸存者> 读后感(现实篇和职业篇)【原创】
    Nest.js你学不会系列-初识Nest
  • 原文地址:https://www.cnblogs.com/wangyongsong/p/6762780.html
Copyright © 2011-2022 走看看