news 2026/2/12 5:19:44

Python中的with语句与try语句:资源管理的两种哲学

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python中的with语句与try语句:资源管理的两种哲学

Python 中的 with 语句 与 try 语句:资源管理的两种哲学

Python 中处理“资源获取 → 使用 → 释放”这一经典模式,主要有两种主流写法,它们背后代表了两种完全不同的设计哲学。

1. 两种写法最直观的对比

# 方式1:经典的 try...finally(显式释放)f=Nonetry:f=open("data.txt","r",encoding="utf-8")content=f.read()# 业务逻辑...finally:iffisnotNone:f.close()
# 方式2:with 语句(上下文管理器,推荐写法)withopen("data.txt","r",encoding="utf-8")asf:content=f.read()# 业务逻辑...# ← 离开 with 块自动关闭(无论正常结束还是异常)

大多数现代 Python 代码(2010 年后)几乎全面转向了with写法。

2. 两种哲学的核心差异

维度try…finally 哲学with 语句(上下文管理器)哲学胜出者(现代主流)
资源释放的责任归属程序员手动负责上下文管理器(对象本身)负责with
释放时机必须显式写在 finally 中自动在离开 with 块时调用(即使抛异常)with
异常安全性容易遗漏 close(),或 finally 写错保证释放(即使exit里抛异常也会尝试释放)with
代码美观度嵌套深、冗长缩进清晰、意图明确with
可组合性多个资源需要多层嵌套 try-finally可多层 with 或 with 同时管理多个资源with
适用范围任何需要清理的场景(文件、网络、锁、数据库等)实现了上下文管理协议的对象(或 @contextmanager)
心智负担高(必须记住每个资源的清理方式)低(只要进入 with 就“忘掉”它)with
错误处理风格命令式(imperative)声明式 + RAII 风格(类似 C++)with(更 pythonic)

3. with 语句底层到底发生了什么?(推荐理解顺序)

withEXPRasVAR:BLOCK

等价于(近似):

manager=EXPR# 获取上下文管理器VAR=manager.__enter__()# 进入时调用exc=Truetry:try:BLOCK# 执行用户代码块except:exc=Falseifnotmanager.__exit__(*sys.exc_info()):raise# 如果 __exit__ 返回 False → 继续抛异常finally:ifexc:manager.__exit__(None,None,None)# 正常退出

关键点:

  • __enter__()返回的值赋给 as 后面的变量(经常是 self 本身)
  • __exit__(exc_type, exc_value, traceback)永远会被调用
  • 如果__exit__返回True,异常被吞掉(不继续向外抛);返回False或不写返回值 → 异常正常向外传播

4. 现代 Python 中常见的 with 用法(2025–2026 视角)

# 多资源同时管理(Python 3.1+)withopen("in.txt")asfin,open("out.txt","w")asfout:fout.write(fin.read())# 上下文管理器 + 异常吞咽(少用,但有用)withsuppress(FileNotFoundError,PermissionError):os.remove("tempfile")# 临时修改上下文(decimal、numpy 等)fromdecimalimportlocalcontext,Decimalwithlocalcontext()asctx:ctx.prec=50print(Decimal(1)/Decimal(7))# 高精度计算# 数据库事务(常见第三方库写法)withconnection:withconnection.cursor()ascursor:cursor.execute("UPDATE ...")# 离开时自动 commit(如果没异常)# 有异常则 rollback# 自己写上下文管理器(最推荐的方式之一)fromcontextlibimportcontextmanager@contextmanagerdeftransaction(db):tx=db.begin()try:yieldtx tx.commit()except:tx.rollback()raisefinally:tx.close()

5. 什么时候还应该用 try…finally?(2025 年仍有场景)

极少数情况:

  1. 需要在 finally 中做与 with 无关的额外清理,且逻辑复杂
  2. 资源对象没有实现上下文管理器,且你无法修改它(老代码、C 扩展)
  3. 非常底层、性能敏感的场景,且你想精确控制每一行(极少)
  4. 需要在 finally 中根据是否发生异常做不同处理(with 的exit可以做到,但写起来稍绕)

绝大多数时候:优先写 with,实在不行再退回到 try-finally

6. 一句话总结(面试/代码审查常用)

“with 语句是 Python 的 RAII(Resource Acquisition Is Initialization),它把资源的生命周期绑定到作用域,而不是手动管理——这几乎是现代 Python 代码中最 pythonic 的资源管理方式。”

你目前项目里资源管理主要用哪种风格?
是全面 with,还是还有很多老的 try-finally?
或者你在写自定义上下文管理器时遇到过什么坑?可以继续聊~

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/7 2:43:59

基于Spring Boot和Activiti6的工作流OA系统设计与实现

基于Spring Boot和Activiti6的工作流OA系统设计与实现 基于Spring Boot和Activiti6的工作流OA系统:企业级应用开发的完美实践 在当今数字化时代,企业对于高效、安全的办公自动化系统需求日益增长。工作流OA系统作为企业信息化建设的核心组成部分&#…

作者头像 李华
网站建设 2026/2/4 5:39:35

基于Spring Boot与Vue的学习教程网站系统设计与实现

基于Spring Boot与Vue的学习教程网站系统设计与实现 基于Spring Boot与Vue的学习教程网站系统:毕业设计源码与论文资源详解 在当今数字化教育时代,在线学习平台已成为知识传播的重要渠道。对于计算机科学或软件工程专业的学生而言,一个功能…

作者头像 李华
网站建设 2026/2/11 23:22:29

基于Springcloud的智能社区服务系统毕业论文+PPT(附源代码+演示视频)

文章目录 一、项目简介1.1 运行视频1.2 🚀 项目技术栈1.3 ✅ 环境要求说明1.4 包含的文件列表 前台运行截图后台运行截图项目部署源码下载 一、项目简介 项目基于SpringBoot框架,前后端分离架构,后端为SpringBoot前端Vue。基于SpringCloud的…

作者头像 李华
网站建设 2026/2/8 12:52:11

学术数据魔法师:书匠策AI如何让你的教育研究“数据开口说话”

在教育研究的江湖里,数据是“武功秘籍”,分析是“内功心法”。但面对堆积如山的数据、晦涩难懂的统计术语,许多研究者(尤其是学生党)常常陷入“数据焦虑”——明明想用数据证明观点,却被工具卡脖子&#xf…

作者头像 李华
网站建设 2026/2/10 7:03:09

能见度监测站 10/50km

Q1:50km能见度监测站的核心定位是什么?与普通能见度监测设备有何不同?A:核心定位是“超远量程能见度精准监测终端”,专注解决低能见度天气下的监测盲区问题,适配公路、高速、机场等对能见度监测要求较高的出…

作者头像 李华
网站建设 2026/2/10 7:03:07

书匠策AI:教育论文的“数据炼金术士”,让数字开口说话的秘密武器——当数据分析不再是“技术苦役”,而是学术创作的灵感源泉

在学术写作的江湖里,数据是“论点的骨骼”,分析是“逻辑的血液”。但面对堆积如山的数据表格、晦涩难懂的统计术语,许多教育研究者常陷入“数据焦虑”:如何让枯燥的数字变成有说服力的故事?如何让复杂的分析变得像拼乐…

作者头像 李华