实现文件上下文管理(__enter__和___exit__)
实现文件上下文管理(__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' * 10) #------------------------------->会执行
出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量
=====>执行代码块
with中代码块执行完毕时执行我啊
<class 'AttributeError'>
***着火啦,救火啊***
<traceback object at 0x1062ab048>
0000000000000
二、模拟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__)的更多相关文章
- 实现文件上下文管理(\_\_enter\_\_和\_\_exit\_\_)
实现文件上下文管理(__enter__和__exit__) 我们知道在操作文件对象的时候可以这么写 with open('a.txt') as f: '代码块' 上述叫做上下文管理协议,即with语句 ...
- python上下文管理器及with语句
with语句支持在一个叫上下文管理器的对象的控制下执行一系列语句,语法大概如下: with context as var: statements 其中的context必须是个上下文管理器,它实现了两个 ...
- Python 上下文管理协议中的__enter__和__exit__基本理解
所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_va ...
- 用python优雅打开文件及上下文管理协议
有次面试被问到如何优雅地打开一个文件? 那就是用with语句,调用过后可以自动关闭. 但是为什么使用with语句就可以自动关闭呢,原因就是上下文管理协议. 上下文管理协议:包含方法 __e ...
- 上下文管理协议with_open,__enter__和__exit__(三十八)
在操作文件对象的时候可以这么写 with open('a.txt') as f: '代码块' 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明__ent ...
- python - 上下文管理协议(with + __enter__ + __exit__)
上下文管理协议: with + __enter__ + __exit__ #上下问管理协议: #with + __enter__ + __exit__ class Test(): def __init ...
- Python概念-上下文管理协议中的__enter__和__exit__
所谓上下文管理协议,就是咱们打开文件时常用的一种方法:with __enter__(self):当with开始运行的时候触发此方法的运行 __exit__(self, exc_type, exc_va ...
- Python上下文管理协议:__enter__和__exit__
上下文管理器(context manager)是Python2.5开始支持的一种语法,用于规定某个对象的使用范围.一旦进入或者离开该使用范围,会有特殊操作被调用 (比如为对象分配或者释放内存).它的语 ...
- python基础----实现上下文管理协议__enter__和__exit__
我们知道在操作文件对象的时候可以这么写 with open('a.txt') as f: '代码块' 上述叫做上下文管理协议,即with语句,为了让一个对象兼容with语句,必须在这个对象的类中声明_ ...
随机推荐
- Pstools使用
pstool的介绍 PsTools是Sysinternals Suite中一款排名靠前的一个安全管理工具套件.现在被微软收购.目前pstools中含有12款各式各样的小工具.如果将它们灵活的运用,将会 ...
- 异步机制 - ReadFileEx(WriteFileEx)
1 ReadFileEx定义 BOOL WINAPI ReadFileEx( __in HANDLE hFile, __out LPVOID lpBuffer, __in DWORD nNumberO ...
- ph:做参考
1 波动学 <伯克利物理学教程>第三卷 上.下册2 场论(朗道)3 场论与粒子物理学(上册)(李政道)出国留学必备书之一!4 场论与粒子物理学(下册)(李政道)5 非平衡态热力 ...
- MapReduce Combiner
Combiner编程(可选步骤,视情况而定!) combiner最基本是实现本地key的归并,combiner具有类似本地的reduce功能. 如果不用combiner,那么所有的结果都是reduce ...
- MySQL索引选择及添加原则
索引选择性就是结果个数与总个数的比值. 用sql语句表示为: SELECT COUNT(*) FROM table_name WHERE column_name/SELECT COUNT(*) FRO ...
- Sql中truncate,delete以及drop的比较
相同点: 1.truncate和不带where子句的delete.以及drop都会删除表内的数据. 2.drop.truncate都是DDL语句(数据定义语言),执行后会自动提交. 不同点: 1. t ...
- shell 變數
echo $? 上个命令的退出状态,或函数的返回值. ref: http://c.biancheng.net/cpp/view/2739.html
- P2047 [NOI2007]社交网络(洛谷)
题目描述 在社交网络 ( Social Network ) 的研究中,我们常常使用图论概念去解释一些社会现象.不妨看这样的一个问题:在一个社交圈子里有 nn 个人,人与人之间有不同程度的关系.我们将这 ...
- mySQL 插入,更新和删除数据
插入数据: 语法: INSERT INTO table_name ( field1, field2,...fieldN ) VALUES ( value1, value2,...valueN ); 如 ...
- 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_12.RabbitMQ研究-工作模式-统配符工作模式测试
路由模式: 1.每个消费者监听自己的队列,并且设置带统配符的routingkey. 2.生产者将消息发给broker,由交换机根据routingkey来转发消息到指定的队列. 创建测试用例 交换机的名 ...