python中的上下文管理器

本文详细解释了Python中with语句的工作原理及其应用场景,包括如何通过with语句简化资源管理,如文件操作,并介绍了上下文管理器的概念及其实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python中,我们会经常使用下面的代码:

with open("1.txt", 'r') as f:
	f.read()
	...

这段代码是用来读某个文件,with在这里可以确保不管使用过程中是否发生异常,都会执行必要的文件关闭操作,释放资源。with语句,简化了代码,有效的避免资源泄漏的发生。

上述代码也可以利用try finally语句完成:

try:
    f = open('1.txt', 'r')
finally:
    if f:
        f.close()

明显看出来这段代码相对更加复杂,python因追求简洁的pythonic编码风格,所以便定义了with写法。

with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放。

上下文管理器

要想理解with,首先要了解上下文管理器,上下文管理器,它是python中的一种协议,实现了这种协议的类的实例,都是上下文管理器对象。

文件的输入输出、数据库的连接断开等,都是很常见的资源管理操作。但资源都是有限的,在写程序时,我们必须保证这些资源在使用过后得到释放,不然就容易造成资源泄露,轻者使得系统处理缓慢,重则会使系统崩溃。上下文管理器,能够帮助你自动分配并且释放资源。

剖析一下上面的with语句:

1. 上下文表达式:with open('test.txt') as f:
2. 上下文管理器:open('test.txt')
3. f是上下文管理器返回的资源对象
4. with关键字表示使用上下文管理器

在python中实现上下文协议并创建上下文管理器对象的方法有两种,一种是基于类的上下文管理器,一种是基于生成器的上下文管理器。

基于类的上下文管理器

用类实现上下文管理器,在类定义的时候,实现两个方法”enter()”和方法“exit()”两个方法即可。其中,方法“enter()”返回需要被管理的资源;方法“exit()”里通常会存在一些释放、清理资源的操作,比如这个例子中的关闭文件等等。

类实现的上下文管理器的例子:
在这里插入图片描述
代码执行的过程:

  1. 方法__init__()被调用,程序初始化对象FileManager,使得文件名(name)是“test.txt”,文件模式(mode)是‘w’
  2. 方法enter()被调用,文件test.txt以写入的模式被打开,并且返回资源对象赋给变量f
  3. 字符串“hello world”被写入文件test.txt
  4. 方法exit()被调用,负责关闭之前打开的文件流

方法“exit()”中的参数“exc_type, exc_val,exc_tb”,分别表示 exception_type、exception_value 和 traceback。当我们执行含有上下文管理器的 with 语句时,如果有异常抛出,异常的信息就会包含在这三个变量中,传入方法“exit()”。

基于生成器的上下文管理器

可以使用装饰器 contextlib.contextmanager,来定义自己所需的基于生成器的上下文管理器,用以支持 with 语句。
在这里插入图片描述
这段代码中,函数 file_manager() 是一个生成器,当我们执行 with 语句时,便会打开文件,并返回文件对象 f;当 with 语句执行完后,finally中的关闭文件操作便会执行。

两种类型的上下文管理器的比较:
基于类的上下文管理器和基于生成器的上下文管理,这两者在功能上是一致的,但:

  • 基于类的上下文管理器更加灵活,适用于大型的系统开发
  • 基于生成器的上下文管理器更加方便、简洁,适用于中小型程序

其他讲解python上下文管理器的文章:
https://www.jianshu.com/p/20fd3335648a
https://www.liaoxuefeng.com/wiki/1016959663602400/1017607179232640
https://blog.youkuaiyun.com/Kwoky/article/details/106682609
https://blog.youkuaiyun.com/Kwoky/article/details/106682609
https://www.runoob.com/python3/python-with.html
https://www.cnblogs.com/wongbingming/p/10519553.html
https://juejin.cn/post/6993180184178327582

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的贝塔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值