Python上下文管理器详解|with语句、上下文函数、contextlib自动资源释放(零基础吃透)
一、什么是上下文管理器?
1.1 概念
上下文管理器(Context Manager):专门用于资源的自动开启与自动释放的语法工具。
简单理解:进入代码块自动预处理,退出代码块自动收尾,哪怕代码报错也能保证资源关闭。
1.2 解决什么问题?
日常开发中很多资源必须手动关闭,否则会造成资源泄露、占用内存、文件锁定:
数据库连接必须 close
网络请求、socket 连接必须断开
二、with 语句基础使用(最常用)
2.1 传统文件操作(缺点:容易忘记关闭、报错不关闭)
f = open("test.txt", "w", encoding="utf-8")
f.write("hello python")
f.close() # 必须手动关闭
2.2 with 上下文写法(推荐)
自动打开、自动关闭、代码报错也会关闭
with open("test.txt", "w", encoding="utf-8") as f:
f.write("hello 上下文管理器")
# 出了 with 代码块,文件自动关闭
2.3 with 核心优势
无需手动 close()
无论正常结束、异常报错,资源一定释放
代码简洁、安全、规范
三、上下文管理器底层原理(必考)
一个对象能被 with 使用,必须实现两个魔法方法:
-
__enter__(self):进入上下文时触发(开启资源)
-
__exit__(self, exc_type, exc_val, exc_tb):退出上下文时触发(释放资源)
执行流程
with 对象 as 变量:
-
先执行
__enter__,返回值赋值给 as 后的变量 -
执行 with 内部代码块
-
代码结束/报错,自动执行
__exit__完成收尾
四、自定义上下文管理类(手写原理)
手动实现一个属于自己的上下文管理器,彻底吃透底层。
class MyContext:
# 进入上下文触发
def __enter__(self):
print("【进入上下文】开启资源")
return self
# 退出上下文触发
def __exit__(self, exc_type, exc_val, exc_tb):
print("【退出上下文】释放资源")
# 返回True 表示异常被忽略
return True
def work(self):
print("执行业务逻辑")
# 使用自定义上下文
with MyContext() as obj:
obj.work()
运行结果
【进入上下文】开启资源 执行业务逻辑 【退出上下文】释放资源
五、上下文函数(重点:contextlib)
如果不想写类、不想写魔法方法,Python 提供极简方案:contextlib
@contextmanager 装饰器可以把一个普通函数变成「上下文函数」
5.1 上下文函数标准结构
yield 之前:对应 __enter__ 开启操作
yield:返回内容,供外部使用
yield 之后:对应 __exit__ 关闭收尾操作
5.2 实战:自定义上下文函数
from contextlib import contextmanager
@contextmanager
def my_context_func():
# 1. 开启资源(enter)
print("函数上下文:开启连接/资源")
# 向外返回数据
yield "我是上下文返回内容"
# 2. 释放资源(exit)
print("函数上下文:关闭连接/资源")
# 调用上下文函数
with my_context_func() as res:
print("上下文内部执行逻辑,获取返回值:", res)
输出结果
函数上下文:开启连接/资源
上下文内部执行逻辑,获取返回值: 我是上下文返回内容
函数上下文:关闭连接/资源
六、上下文函数模拟文件操作(超经典案例)
from contextlib import contextmanager
@contextmanager
def open_file(path, mode, encoding="utf-8"):
# 打开文件
f = open(path, mode, encoding=encoding)
try:
yield f # 交给外部使用
finally:
# 无论如何都会关闭文件
f.close()
print("文件已自动关闭")
# 使用自定义文件上下文
with open_file("demo.txt", "w") as f:
f.write("测试上下文函数")
print("文件写入完成")
这就是Python原生open的底层思想!
七、异常安全机制(核心特性)
上下文最大的意义:代码报错也能自动收尾
from contextlib import contextmanager
@contextmanager
def test_err():
print("开启资源")
yield
print("释放资源")
with test_err():
print("执行代码")
1 / 0 # 主动报错
即使代码报错,依然会执行收尾的释放逻辑。
文件读写:自动 open / close
八、日常开发使用场景总结
数据库连接:自动连接、自动关闭
网络请求、Socket:自动断开
线程锁 Lock:自动加锁、自动解锁
代码计时、日志上下文:统一前置后置操作
九、全文核心总结
-
上下文管理器作用:自动开启、自动释放资源,安全优雅;
-
类实现依靠:__enter__、__exit__两个魔法方法;
-
函数实现依靠:@contextmanager 装饰器,最简写法;
-
yield 前开启资源,yield 后关闭资源;
-
无论代码正常/异常,都能保证资源释放,杜绝内存泄露。
✨ 点赞收藏!Python高阶语法全套完结,适合期末作业、面试背诵!
更多推荐
所有评论(0)