__enter__,__exit__
- 我们知道在操作文件对象的时候可以这么写
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'>
三、优点
使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预
在需要管理一些资源比如文件,网络连接和锁的编程环境中,可以在__exit__中定制自动释放资源的机制,你无须再去关系这个问题,这将大有用处
__enter__,__exit__的更多相关文章
- python - 上下文管理协议(with + __enter__ + __exit__)
上下文管理协议: with + __enter__ + __exit__ #上下问管理协议: #with + __enter__ + __exit__ class Test(): def __init ...
- __enter__,__exit__上下文管理协议
上下文管理协议__enter__,__exit__ 用途或者说好处: 1.使用with语句的目的就是把代码块放入with中执行,with结束后,自动完成清理工作,无须手动干预 2.在需要管理一些资源比 ...
- python中的__enter__ __exit__
我们前面文章介绍了迭代器和可迭代对象,这次介绍python的上下文管理.在python中实现了__enter__和__exit__方法,即支持上下文管理器协议.上下文管理器就是支持上下文管理器协议的对 ...
- with语句与__enter__,__exit__
class Foo(object): def func(self): print("func") pass def __enter__(self): print("ent ...
- __enter__,__exit__区别
__enter__():在使用with语句时调用,会话管理器在代码块开始前调用,返回值与as后的参数绑定 __exit__():会话管理器在代码块执行完成好后调用,在with语句完成时,对象销毁之前调 ...
- python-open文件处理
python内置函数open()用于打开文件和创建文件对象 语法 open(name[,mode[,bufsize]]) name:文件名 mode:指定文件的打开模式 r:只读 w:写入 a:附加 ...
- 【python】with的实现方法
来源:http://www.ibm.com/developerworks/cn/opensource/os-cn-pythonwith/#icomments 重点: with方法适用于需要分配和清理资 ...
- python的with...as用法
with...as叫做上下文管理器,作用是进入一个对象的作用域和离开时,可以执行执行一定的操作.这个操作是可以自己 设定的. 写个例子学习一下: class test(): def __init__( ...
- When to close cursors using MySQLdb
http://stackoverflow.com/questions/5669878/when-to-close-cursors-using-mysqldb I'm building a WSGI w ...
随机推荐
- java之折半查找
//功能:二分查找import java.util.*; public class Demo1 { public static void main(String[] args) { int arr[] ...
- MFC窗口消息PostMessage和SendMessage
以前这些消息用得比较少,但是今天碰到了个事儿,我看非用消息不可. 事情是这样的,我在线程中需要刷新对话框上面的内容,但是每每执行到UpdateData时就出现了断言错误. 查了相关资料,发现这个可能是 ...
- Codeforces Round #374 (Div. 2) C. Journey —— DP
题目链接:http://codeforces.com/contest/721/problem/C C. Journey time limit per test 3 seconds memory lim ...
- selenium使用笔记(一)——selenium你该知道的
有时候在交流群里经常会看到这样的问题,selenium能进行性能测试吗?selenium1和selenium2有什么区别等等问题,在这里谈一下自己学习和工作以后对selenium的认识.我所记录的东西 ...
- 转:Windows下WSH/JS实现SVN服务器钩子脚本阻止提交空日志信息和垃圾文件
http://blog.csdn.net/caikanxp/article/details/8279921 如何强制用户在提交SVN时填写日志信息? 如果用户使用的都是TortoiseSVN客户端,可 ...
- TensorFlow 图像预处理(一) 图像编解码,图像尺寸调整
from: https://blog.csdn.net/chaipp0607/article/details/73029923 TensorFlow提供了几类图像处理函数,下面介绍图像的编码与解码,图 ...
- DGA域名——可以每天只生成一个域名,因此最多存在365个 DGA域名;
Mirai变种中的DGA 分享到: 发布时间:2016-12-12 16:02:57 作者:360网络安全研究院 投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿 那个导致美国断网 ...
- Linux命令学习笔记- vmstat命令实战详解
vmstat命令是最常见的Linux/Unix监控工具,可以展现给定时间间隔的服务器的状态值,包括服务器的CPU使用率,内存使用,虚拟内存交换情况,IO读写情况.这个命令是我查看Linux/Unix最 ...
- multi_socket
threading_test.py #threading #为什么在命令行可以执行,F5不能执行 #线程处理能导致同步问题 from socketserver import TCPServer,Thr ...
- Java并发之synchronized
Java多线程同步关键词是常用的多线程同步手段.它可以修饰静态类方法,实例方法,或代码块.修饰static静态方法时是对整个类加锁. 一.实现原理 在JVM中对象内存分三块区域,对象头.实例数据.对齐 ...