news 2026/8/25 6:56:48

Python 上下文管理器 with ~

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python 上下文管理器 with ~

核心作用:进入时做资源打开,退出时自动执行清理(shutdown/close),就算抛异常也一定会执行,不用手动写 try‑finally

1. 两种写法

方式1:直接使用现成支持 with 的对象(日常最多)

很多库自带__enter__/__exit__,直接套with

# 文件,退出自动closewithopen("test.txt","r",encoding="utf‑8")asf:data=f.read()# 数据库连接、线程锁、http session 都是同理

离开 with 代码块,自动调用.close(),发生异常也会关闭。


方式2:自己实现类的上下文管理器(自定义,自动 shutdown)

实现两个魔术方法:

  • __enter__:进入with块时执行,返回值给as 变量
  • __exit__:退出块时无论正常/异常都会执行,做 shutdown、释放资源
classMyClient:def__init__(self):passdefstart(self):"""启动连接"""print("启动连接")defshutdown(self):"""销毁、关闭资源"""print("执行 shutdown,释放连接")def__enter__(self):self.start()returnself# 给到 with ... as objdef__exit__(self,exc_type,exc_val,exc_tb):# exc_type 不为None代表里面抛出了异常self.shutdown()# 返回 True:吃掉异常;返回False/None:向外抛出异常returnFalse# 使用withMyClient()ascli:print("业务逻辑执行")# 哪怕这里抛异常,也会自动走到 shutdown# raise ValueError("出错啦")# 出with块,已经自动shutdown

__exit__的三个参数:异常类型、异常实例、堆栈。不需要处理异常直接忽略即可。


方式3:@contextmanager装饰器(写起来最简,工程代码最常用)

不用写类,用生成器函数,yield之前是进入逻辑,yield之后是退出/清理逻辑

⚠️ yield 后面的代码,哪怕内部抛异常依然会执行,非常适合做 shutdown。

fromcontextlibimportcontextmanager@contextmanagerdefmy_resource():# ========== enter 阶段:打开资源 ==========print("打开资源")try:yield"资源对象"# 这里产出的值给到 as 后面变量finally:# ========== exit 阶段:一定会执行,shutdown/释放 ==========print("自动执行 shutdown,释放资源")# 调用withmy_resource()asres:print(f"使用:{res}")# raise Exception("模拟报错")# 出with,已经释放

这是写工具、封装客户端最推荐的写法,代码短。

要点

  1. with本质就是语法糖,等价手写try‑finally
obj=MyClient()obj.__enter__()try:# 业务代码finally:obj.__exit__(...)
  1. __exit__/ finally 一定会跑,但是不能保证进程被 os kill 的场景(系统强杀进程,Python 代码没机会执行清理)。
  2. 大模型/向量库场景常见:把客户端、Milvus 连接、MinerU http session 包成上下文管理器,出块自动关闭连接。

极简对比总结

写法适用场景
直接 with 对象库已经实现好,日常读写文件、锁、session
class +__enter__/__exit__需要复杂类实例,要维护大量成员属性
@contextmanager轻量封装,只需要打开‑关闭逻辑,工程最常用
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/25 6:55:36

本地优先的 AI LaTeX 写作台:写论文不怕断网泄密

1. 引言 写论文的人,往往都经历过这样的崩溃时刻:网络断线、排版到一半的 LaTeX 工程打不开;或是在线写作工具突然抽风,辛辛苦苦写的内容进了“别人的服务器”还无法导出;更让人不安的是,尚未发表的研究数据…

作者头像 李华
网站建设 2026/8/25 6:55:13

游戏耳机选购指南:平坦频率响应与舒适佩戴如何提升FPS竞技体验

最近在逛社区时,发现一个挺有意思的现象:很多玩家,尤其是刚入坑FPS(第一人称射击)游戏的玩家,在挑选耳机时特别容易陷入一个误区——认为“听声辨位”是游戏耳机最核心、甚至唯一的功能。于是,预…

作者头像 李华
网站建设 2026/8/25 6:54:05

Python 魔术方法

Python 魔术方法(Magic Method / 双下划线方法 __xxx__)特征:前后双下划线 __名字__,又叫特殊方法。 你不要手动直接调用它,Python解释器会在特定语法、内置操作触发时自动调用。举个直观例子: obj obj2 …

作者头像 李华
网站建设 2026/8/25 6:53:08

DeepSeek Harness:从零构建可追溯的AI编程工作流

最近在探索 AI 编程工具时,发现了一个非常有意思的新项目——DeepSeek Harness。它不像传统的代码生成工具那样,给你一个黑盒结果就结束了,而是将整个 AI 交互过程拆解成一个个可插拔、可追溯的“插件”。无论是代码生成、代码审查&#xff0…

作者头像 李华
网站建设 2026/8/25 6:50:33

[063][调度模块]事件驱动的日志记录与高效查询体系

[063][调度模块]事件驱动的日志记录与高效查询体系 本文章代码: gitee , gitcode , github 1. 事件驱动架构:解耦调度与日志 任务状态变更时,ScheduleTaskManager 发布 ChangeStatusEvent,JobLogEventConsumer 异步消费(需配置…

作者头像 李华