• 我们知道在操作文件对象的时候可以这么写
with open('a.txt') as 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)
出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量
=====>执行代码块
with中代码块执行完毕时执行我啊
  • __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) try:
with Open('a.txt') as f:
print('=====>执行代码块')
raise AttributeError('***着火啦,救火啊***')
except Exception as e:
print(e)
出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量
=====>执行代码块
with中代码块执行完毕时执行我啊
<class 'AttributeError'>
***着火啦,救火啊***
<traceback object at 0x1065f1f88>
***着火啦,救火啊***
  • 如果__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语句,对象的__enter__被触发,有返回值则赋值给as声明的变量
=====>执行代码块
with中代码块执行完毕时执行我啊
<class 'AttributeError'>
***着火啦,救火啊***
<traceback object at 0x1062ab048>
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

二、模拟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):
return getattr(self.f, item) with Open('a.txt', 'w') as f:
print(f)
f.write('aaaaaa')
f.wasdf #抛出异常,交给__exit__处理
<_io.TextIOWrapper name='a.txt' mode='w' encoding='utf-8'>

三、优点

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

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

__enter__,__exit__的更多相关文章

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

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

  2. __enter__,__exit__上下文管理协议

    上下文管理协议__enter__,__exit__ 用途或者说好处: 1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预 2.在需要管理一些资源比 ...

  3. python中的__enter__ __exit__

    我们前面文章介绍了迭代器和可迭代对象,这次介绍python的上下文管理.在python中实现了__enter__和__exit__方法,即支持上下文管理器协议.上下文管理器就是支持上下文管理器协议的对 ...

  4. with语句与__enter__,__exit__

    class Foo(object): def func(self): print("func") pass def __enter__(self): print("ent ...

  5. __enter__,__exit__区别

    __enter__():在使用with语句时调用,会话管理器在代码块开始前调用,返回值与as后的参数绑定 __exit__():会话管理器在代码块执行完成好后调用,在with语句完成时,对象销毁之前调 ...

  6. python-open文件处理

    python内置函数open()用于打开文件和创建文件对象 语法 open(name[,mode[,bufsize]]) name:文件名 mode:指定文件的打开模式 r:只读 w:写入 a:附加 ...

  7. 【python】with的实现方法

    来源:http://www.ibm.com/developerworks/cn/opensource/os-cn-pythonwith/#icomments 重点: with方法适用于需要分配和清理资 ...

  8. python的with...as用法

    with...as叫做上下文管理器,作用是进入一个对象的作用域和离开时,可以执行执行一定的操作.这个操作是可以自己 设定的. 写个例子学习一下: class test(): def __init__( ...

  9. When to close cursors using MySQLdb

    http://stackoverflow.com/questions/5669878/when-to-close-cursors-using-mysqldb I'm building a WSGI w ...

随机推荐

  1. EasyDarwin EasyCamera支持海康摄像机接入了

    本文转自EasyDarwin开源团队成员Alex的博客:http://blog.csdn.net/cai6811376/article/details/52709816 EasyCamera默认使用海 ...

  2. Vue 单页面应用 SEO SPA single page application advantages and disadvantages

    处理 Vue 单页面应用 SEO 的另一种思路 - muwoo - 博客园 https://www.cnblogs.com/tiedaweishao/p/7493971.html SPA网站SEO完美 ...

  3. 【洛谷 2405】 non天平

    题目背景 non最近正在为自己的体重而苦恼,他想称量自己的体重.于是,他找来一个天平与许多砝码. 题目描述 砝码的重量均是n的幂次,n^1.n^2.n^3.n^4.n^5的……non想知道至少要多少个 ...

  4. 大数据之ES系列——第一篇 ElasticSearch2.2 集群安装部署

    第一部分  安装准备 准备三台主机节点: hc11.spads  192.168.160.181 hc12.spads  192.168.160.182 hc13.spads  192.168.160 ...

  5. 剑指Offer:树的子结构【26】

    剑指Offer:树的子结构[26] 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 解题思路 分为两步: 第一步:在树A中找到和树B的根节点的值一 ...

  6. 将自定义参数从uboot传入kernel的并读取的方法【转】

    本文转载自:http://blog.csdn.net/qq_29729577/article/details/50580727 希望朋友们多多指点,好的技术或心得一起分享: uboot向kernel传 ...

  7. HDU4565 So Easy! —— 共轭构造、二阶递推数列、矩阵快速幂

    题目链接:https://vjudge.net/problem/HDU-4565 So Easy! Time Limit: 2000/1000 MS (Java/Others)    Memory L ...

  8. linux命令行快捷键记录

    摘自: http://www.cnblogs.com/webzhangnan/p/3221410.html [移动光标] Ctrl+A 标移到行首.它在多数文本编辑器和 Mozilla 的 URL 字 ...

  9. JavaWeb学习总结(三)response与request

    一.response response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse.在客户端发出每个请求时,服务器 ...

  10. 上传图片 ajax input type="file" 兼容 ie chroem 火狐

    上传图片,转载请注明出处!!! 兼容 ie chroem 火狐 html: <div id="uploadForm"> <input id="file& ...