• python学习之__enter__和__exit__上下文管理协议


    传统方式:

    open('a.txt')
    文件操作
    x.close()//关闭文件句柄,减少内存浪费

    with open('a.txt') as f open是一个类 f是一个对象
    获取了一个对象 赋值给对象“f”

    上下文管理协议,即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)

    __exit__()中的三个参数分别代表异常类型,异常值和追溯信息,with语句中代码块出现异常,则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)

    with Open('a.txt') as f:
    print('=====>执行代码块')
    raise AttributeError('***着火啦,救火啊***')
    print('0'*100) #------------------------------->不会执行

    如果__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) #------------------------------->会执行

    总结
    with obj as f:
    '代码块'

    1.with obj ----》触发obj.__enter__(),拿到返回值

    2.as f----->f=返回值、

    3.with obj as f 等同于 f=obj.__enter__()

    4.执行代码块
    一:没有异常的情况下,整个代码块运行完毕后去触发__exit__,它的三个参数都为None
    二:有异常的情况下,从异常出现的位置直接触发__exit__
    a:如果__exit__的返回值为True,代表吞掉了异常
    b:如果__exit__的返回值不为True,代表吐出了异常
    c:__exit__的的运行完毕就代表了整个with语句的执行完毕

    用途或者说好处:

    1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预
    2.在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在__exit__中定制自动释放资源的机制,
    你无须再去关系这个问题,这将大有用处

    异常三要素:(是对象就有一个类)
    异常类
    异常值
    traceback追踪信息

  • 相关阅读:
    C# .Net WinForm控件GDI+重绘位置错乱
    查询视图对应的基表名以及视图字段和对应的基表字段名
    解决在高分屏下开发winform界面变形
    ping命令工具:同时ping多个IP
    SmartAssembly批处理用法
    C#二维数组的初始化和存取
    win7 X64 进程名称不一致,导致杀进程失效!
    在存储过程中声明局部游标以循环调用自身
    强制设置双缓冲DoubleBuffered 解决tableLayoutPanel 闪烁
    Using SmartAssembly with MSBuild
  • 原文地址:https://www.cnblogs.com/jinpingzhao/p/12916262.html
Copyright © 2020-2023  润新知