实现文件上下文管理(__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__)的更多相关文章

  1. 实现文件上下文管理(\_\_enter\_\_和\_\_exit\_\_)

    实现文件上下文管理(__enter__和__exit__) 我们知道在操作文件对象的时候可以这么写 with open('a.txt') as f: '代码块' 上述叫做上下文管理协议,即with语句 ...

  2. python上下文管理器及with语句

    with语句支持在一个叫上下文管理器的对象的控制下执行一系列语句,语法大概如下: with context as var: statements 其中的context必须是个上下文管理器,它实现了两个 ...

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 文件对比工具 Beyond Compare 4.2.9中文破解版for win 附通用注册码

    链接: https://pan.baidu.com/s/1yYxPo8nNv0PuOA1ZC9-F1w 提取码: v76g 注册码: --- BEGIN LICENSE KEY --- H1bJTd2 ...

  2. Spring Cloud Config(一):聊聊分布式配置中心 Spring Cloud Config

    目录 Spring Cloud Config(一):聊聊分布式配置中心 Spring Cloud Config Spring Cloud Config(二):基于Git搭建配置中心 Spring Cl ...

  3. 【原创】FltSendMessage蓝屏分析

    INVALID_PROCESS_DETACH_ATTEMPT (6)Arguments:Arg1: 00000000Arg2: 00000000Arg3: 00000000Arg4: 00000000 ...

  4. 在一串字符串中找到与正则表达式匹配的字符串?(例如:export_20170717_out.log 找到20170717)

    如题:提取字符串:export_20170717_out.log 对应的日期: package dodo; import java.util.regex.Matcher; import java.ut ...

  5. 我用asp.net core 部署到docker遇到的问题

    1.怎么部署 我是用文件的形式先发布出来,然后把文件拷贝到服务器上部署到docker中去. 2.端口映射 根据查找到的资料,dockerfile 是不支持指定映射服务器端口的,只能在run的时候用-p ...

  6. mysql 远程登陆

    1.查询mysql是否启动 netstat  -lnp|grep   3306 ps -df |grep  mysqld 2.通过TCPIP的方式测试连接 mysql -uqingjiao -padm ...

  7. SpringBoot/SpringMVC 下载本地文件

    页面代码: <!DOCTYPE html> <html lang="utf-8"> <meta http-equiv="Content-Ty ...

  8. Java同步数据结构之LinkedTransferQueue

    前言 LinkedTransferQueue是Java并发包中最强大的基于链表的无界FIFO阻塞传输队列.从JDK7开始出现,Doug Lea说LinkedTransferQueue是Concurre ...

  9. hadoop2.7.7+habse2.0.5+zookeeper3.4.14+hive2.3.5单机安装

    环境 腾讯云centos7 1.hadoop下载 http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-2.7.7/hadoop-2.7.7.tar ...

  10. Hibernate fetch相关

    fetch=FetchType.LAZY 时,spring boot jackson 返回数据时会出错. 可配置使用Hibernate4Module 帮助解决: @Configurationpubli ...