上下文管理协议__enter__,__exit__

用途或者说好处:

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

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

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

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

上述叫做上下文管理协议,即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. with Open('a.txt') as f:
  12. print('=====>执行代码块')
  13. # print(f,f.name)

__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. with Open('a.txt') as f:
  15. print('=====>执行代码块')
  16. raise AttributeError('***着火啦,救火啊***')
  17. print(''*100) #------------------------------->不会执行

如果__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. with Open('a.txt') as f:
  16. print('=====>执行代码块')
  17. raise AttributeError('***着火啦,救火啊***')
  18. print(''*100) #------------------------------->会执行

其实看这个就行,讲的所有的点

  1. class Foo:
  2. def __init__(self,name):
  3. self.name = name
  4.  
  5. def __enter__(self):
  6. print('执行了__enter__方法')
  7. return self #返回实例化对象给f
  8. def __exit__(self, exc_type, exc_val, exc_tb):
  9. print('执行了__exit__方法')
  10. #如果爆出异常后,exc_type, exc_val, exc_tb会捕捉到错误信息,如果没有错误,三个参数值为None
  11. print(exc_type) #<class 'NameError'> 错误类型,也就是错误类
  12. print(exc_val) #name 'aaaaa' is not defined #错误位置,也就是异常值
  13. print(exc_tb) #<traceback object at 0x00000011F51B9988> #没啥用,也就是追逐信息
  14. return True #在有异常后,如果__exit__执行结果返回的是True,不会报错,返回其它,会报错
  15. with Foo('a.txt') as f: #with 实例化的一个对象,会触发对象属性中的__enter__方法
  16. print(f) #__enter__方法返回值给f,f可拿到Foo实例化后的对象
  17. print(f.name) #可拿到实例化的信息
  18. print(aaaaa) #会抛出异常,抛出异常后会触发__exit__的运行,
  19. # 1、如果__exit__的返回值为True,代表吞掉了异常信息(就是不会报错)
  20. # 2、如果__exit__的返回值不为True,代表吐出了异常信息(就是会报错)
  21. print('不会执行')
  22. print('不会执行')
  23. print('不会执行')
  24. print('------------------------')

__enter__,__exit__上下文管理协议的更多相关文章

  1. __enter__ 和 __exit__上下文管理协议

    class F: def __init__(self,n): self.n = n def __enter__(self): print('执行enter') return self def __ex ...

  2. Python 上下文管理协议中的__enter__和__exit__基本理解

    所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_va ...

  3. 上下文管理协议with_open,__enter__和__exit__(三十八)

    在操作文件对象的时候可以这么写 with open('a.txt') as f: '代码块' 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__ent ...

  4. python - 上下文管理协议(with + __enter__ + __exit__)

    上下文管理协议: with + __enter__ + __exit__ #上下问管理协议: #with + __enter__ + __exit__ class Test(): def __init ...

  5. Python概念-上下文管理协议中的__enter__和__exit__

    所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_va ...

  6. Python上下文管理协议:__enter__和__exit__

    上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围.一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存).它的语 ...

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

    我们知道在操作文件对象的时候可以这么写 with open('a.txt') as f: '代码块' 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明_ ...

  8. 上下文管理协议with open as

    我们知道在操作文件对象的时候可以这么写 with open('a.txt') as f: '代码块' 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明_ ...

  9. 用python优雅打开文件及上下文管理协议

    有次面试被问到如何优雅地打开一个文件?   那就是用with语句,调用过后可以自动关闭.   但是为什么使用with语句就可以自动关闭呢,原因就是上下文管理协议.   上下文管理协议:包含方法 __e ...

随机推荐

  1. 绝对定位(absolute)

    绝对定位(absolute),作用是将被赋予此定位方法的对象从文档流中拖出,使用left,right,top, bottom等属性相对于其最接近的一个最有定位设置的父级对象进行绝对定位,如果对象的父级 ...

  2. MySQL学习笔记(四)——分组数据group by子句和having子句

    分组允许把数据分为多个逻辑组,以便对每个组进行聚集计算. 例如我们查下每个系里有多少名学生: 在使用group by 子句之前,还需要知道一些规定: 1. group by 子句可以包含任意数目的列, ...

  3. ansible-playbook初始化服务器

    hosts ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ [test] 0.0.0.0 ansible_ssh_us ...

  4. ffmpeg 的一些学习网站

    http://blog.csdn.net/leixiaohua1020/article/category/1360795 雷霄骅(leixiaohua1020)的专栏 http://dranger.c ...

  5. BZOJ 1620 [Usaco2008 Nov]Time Management 时间管理:贪心

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1620 题意: 有n个工作,每一个工作完成需要花费的时间为tim[i],完成这项工作的截止日 ...

  6. get_extension_funcs 返回某个模块下的所有函数

    array get_extension_funcs ( string $module_name )             (参数必选) 该函数根据 module_name 返回模块内定义的所有函数的 ...

  7. Java中的final和static

    final final可以用在类.方法.变量上. 1.final用在类上,表明当前类它不能被继承,没有子类. 2.final用在方法上,表明当前方法不能被override,不能被重写. 3.final ...

  8. 「AHOI2008」「LuoguP4281」紧急集合 / 聚会(LCA

    题目描述 欢乐岛上有个非常好玩的游戏,叫做“紧急集合”.在岛上分散有N个等待点,有N-1条道路连接着它们,每一条道路都连接某两个等待点,且通过这些道路可以走遍所有的等待点,通过道路从一个点到另一个点要 ...

  9. Day01:Python入门

    一.编程与编程语言 编程的目的是将人类的思想流程按照某种能够被计算机识别的表达方式传递给计算机,从而让计算机能像人脑一样自动执行工作. 能被计算机所识别的表达方式是编程语言,python就是一门编程语 ...

  10. dockerfile_nginx+PHP+mongo数据库_完美搭建

      基于dockerfile创建nginx+PHP+mongo数据库_完美搭建     第一步:   从git上:git clone http://git.oursdata.com/wangyue/d ...