with语句和上下文管理器
1. with语句的使用
向文件中写入数据的示例代码:
# 1、以写的方式打开文件f = open("1.txt", "w")# 2、写入文件内容f.write("hello world")# 3、关闭文件f.close()
代码说明:
- 文件使用完后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的
这种写法可能出现一定的安全隐患,错误代码如下:
# 1、以读的方式打开文件f = open("1.txt", "r")# 2、读取文件内容f.write("hello world")# 3、关闭文件f.close()
运行结果:
代码说明:
- 由于文件读写时都有可能产生IOError,一旦出错,后面的f.close()就不会调用。
- 为了保证无论是否出错都能正确地关闭文件,我们可以使用try ... finally来解决
安全写法, 代码如下:
try:# 1、以读的方式打开文件f = open("1.txt", "r")# 2、读取文件内容f.write("xxxxx")except IOError as e:print("文件操作出错", e)finally:# 3、关闭文件f.close()
运行结果:
这种方法虽然代码运行良好,但是缺点就是代码过于冗长,并且需要添加try-except-finally语句,不是很方便,也容易忘记.
在这种情况下,Python提供了 with 语句的这种写法,既简单又安全,并且 with 语句执行完成以后自动调用关闭文件操作,即使出现异常也会自动调用关闭文件操作。
with 语句的示例代码:
# 1、以写的方式打开文件
with open("1.txt", "w") as f:# 2、读取文件内容f.write("hello world")
2. 上下文管理器
一个类只要实现了__enter__()和__exit__()
这两个方法,通过该类创建的对象我们就称之为上下文管理器。
上下文管理器可以使用 with 语句,with语句之所以这么强大,背后是由上下文管理器做支撑的,也就是说刚才使用 open 函数创建的文件对象就是就是一个上下文管理器对象。
自定义上下文管理器类,模拟文件操作:
定义一个File类,实现 __enter__() 和 __exit__()
方法,然后使用 with 语句来完成操作文件, 示例代码:
class File(object):# 初始化方法def __init__(self, file_name, file_model):# 定义变量保存文件名和打开模式self.file_name = file_nameself.file_model = file_model# 上文方法def __enter__(self):print("进入上文方法")# 返回文件资源self.file = open(self.file_name,self.file_model)return self.file# 下文方法def __exit__(self, exc_type, exc_val, exc_tb): # 里面参数是固定的,会自动生成print("进入下文方法")self.file.close()if __name__ == '__main__':# 使用with管理文件with File("1.txt", "r") as file:file_data = file.read()print(file_data)
运行结果:
代码说明:
__enter__
表示上文方法,需要返回一个操作文件对象__exit__
表示下文方法,with语句执行完成会自动执行,即使出现异常也会执行该方法。
3. 上下文管理器的另外一种实现方式
假如想要让一个函数成为上下文管理器,Python 还提供了一个 @contextmanager 的装饰器,更进一步简化了上下文管理器的实现方式。通过 yield 将函数分割成两部分,yield 上面的语句在 __enter__
方法中执行,yield 下面的语句在 __exit__
方法中执行,紧跟在 yield 后面的参数是函数的返回值。
# 导入装饰器
from contextlib import contextmanager# 装饰器装饰函数,让其称为一个上下文管理器对象
@contextmanager
def my_open(path, mode):try:# 打开文件file = open(path, mode)# yield之前的代码好比是上文方法yield fileexcept Exception as e:print(e)finally:print("over")# yield下面的代码好比是下文方法file.close()# 使用with语句
with my_open('1.txt', 'w') as f:f.write("hello , the simplest context manager")
4. 小结
- Python 提供了 with 语句用于简化资源释放的操作,使用 with 语句操作建立在上下文管理器(实现
__enter__和__exit__
)的基础上 - Python 还提供了一个 @contextmanager 装饰器,更进一步简化上下管理器的实现,让一个函数可以成为上下文管理器,结合 with 语句来使用
with语句和上下文管理器相关推荐
- 第十章、python字符串操作与with语句及上下文管理器------字符串的匹配与查找
目录 10.1 python的字符串的操作 10.1.1 python的字符串的匹配与查找 (1)实例 (2)find(或rfind).index(或rindex)与match.search.find ...
- Python3中上下文管理器介绍
在任何编程语言中,文件操作或数据库连接等资源的使用都很常见.但这些资源供应有限.因此,主要问题在于确保在使用后释放这些资源.如果不释放它们,则会导致资源泄漏,并可能导致系统变慢或崩溃.如果用户有一个自 ...
- python-->with-上下文管理器
1.概念 含有__enter__和__exit__方法的对象就是上下文管理器 2.语法 whith 上下文管理器:代码块 3.使用场景 只要创建/打开用完需要关闭时就可以用with实现,例如socke ...
- python with和上下文管理工具
源链接:https://zhuanlan.zhihu.com/p/27051142 如果你有阅读源码的习惯,可能会看到一些优秀的代码经常出现带有 "with" 关键字的语句,它通常 ...
- Python学习之路33-上下文管理器和else块
<流畅的Python>笔记. 本篇主要讨论Python用户常忽略掉的一些流程控制特性,包括上下文管理器和else块.内容包括else与非if关键字的搭配:Python中的上下文管理器,如何 ...
- Python--上下文管理器学习(11.3)
直接上代码: #python上下文管理器 #with用法 with open('E:\\DemoTestData\\demo.txt','w') as f:f.write('hello')#实现效果: ...
- Flask的状态保持和上下文管理
状态保持 因为 http 是一种无状态协议,浏览器请求服务器是无状态的. 无状态:指一次用户请求时,浏览器.服务器无法知道之前这个用户做过什么,每次请求都是一次新的请求. 无状态原因:浏览器与服务器是 ...
- 读书笔记:《流畅的Python》第15章 上下文管理器和else块
# 第15章 上下文管理器和else块""" 本章内容提要:with语句和上下文管理器for while try语句的else子句 """# ...
- 云学python (第5章对象带你飞之储存 上下文管理器pickle 包)《vamei-从Python开始学编程》 笔记
2.上下文管理器 文件操作常常和上下文管理器一起使用.上下文管理器(context manager)用于规定某个对象的使用范围.一旦进入或者离开该使用范围, 则会有特殊操作被调用,比如为对象分配或者释 ...
最新文章
- 【PAT (Basic Level) 】1025 反转链表 (25 分)
- Python让你成为AI 绘画大师,简直太惊艳了!(附代码))
- 新车模、新舵机、新体验
- linux ssh远程登录 配置文件 sshd_config 介绍
- php语言中 类的关键词是,c语言中的关键字有哪些类型?
- yolo-v2 v3实现笔记 mAP:mean average precision 平均精度均值
- Python连接mysql基本操作
- 一次900万+数据量的 SQL 查询优化分析【上百倍性能优化】
- 如何在MySQL中设置外键约束
- .net @什么意思_.NET和F#周报2019-4 各地微软技术俱乐部汇总 ML.NET 0.10
- 【leetcode-101】 对称二叉树
- GET 和 POST 有什么区别?
- 哪些高级感中文Logo字体可免费商用?
- FPGA参数定义 regwire 详解
- 鸿蒙方舟UI开发框架-eTS状态管理
- Java 生成舒尔特方格
- 从0到10W粉,这一年我在csdn的成长之路
- 2023二建各科入门帮助
- Java 后端开发实践 - 项目模板(16 步)
- PCIe系列第三讲、事务层通用 TLP 头结构分析