• 十六. 面向对象上下文管理协议


    一. __enter__和__exit__

    我们知道在操作文件对象的时候可以这么写
    
    1 with open('a.txt') as f:
    2   '代码块'
    上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__enter__和__exit__方法
    
    # 上下文管理协议
    class Open:
        def __init__(self,name):
            self.name=name
    
        def __enter__(self):
            print('出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量')
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            print('with中代码块执行完毕时执行我啊')
    
    with Open('a.txt') as f:
        print('执行代码块')
        print(f, f.name)
    # 执行顺序 # 出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量 # 执行代码块 # <__main__.Open object at 0x00000291C6EE8898> a.txt # with中代码块执行完毕时执行我啊
    如果__exit()返回值为True,那么异常会被清空,就好像啥都没发生一样,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) #------------------------------->会执行
    # 模拟Open
    
    class Open:
        def __init__(self,filepath,mode='r',encoding='utf-8'):
            self.filepath=filepath
            self.mode=mode
            self.encoding=encoding
    
        def __enter__(self):
            # print('enter')
            self.f=open(self.filepath,mode=self.mode,encoding=self.encoding)
            return self.f
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            # print('exit')
            self.f.close()
            return True
        def __getattr__(self, item):
            print(item)
            return getattr(self.f,item)
    
    with Open('aa','r') as f:
        print(f)
        print(   f.read())
    
        f.wasdf #抛出异常,交给__exit__处理
    
    # 
    # 用途或者说好处:
    # 
    # 1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预
    # 
    # 2.在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在__exit__中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处
  • 相关阅读:
    Redis Pipeline原理分析
    python 装饰器,传递类以及参数
    q
    Redis的EXPIRE过期机制介绍
    z
    julia .文档
    julia 安装
    python 弧度与角度互转
    python 角度和弧度转化
    机器人行业中我们常说的roll、yaw、pitch是什么?
  • 原文地址:https://www.cnblogs.com/Sup-to/p/11087342.html
Copyright © 2020-2023  润新知