Python with 语句与上下文管理讲解
文章目录一、为什么需要 with二、基本语法三、上下文管理器协议四、自定义上下文管理器的两种方式1. 基于类的实现2. 基于生成器的实现推荐更简洁五、__exit__ 的三个参数六、常见实际应用场景七、contextlib 常用工具八、最佳实践with语句是 Python 中用于上下文管理Context Management的语法糖最核心的作用是确保资源被正确获取和释放即使中间发生异常也能保证清理工作被执行。一、为什么需要with传统写法打开文件fopen(test.txt,r,encodingutf-8)try:dataf.read()finally:f.close()# 必须手动关闭问题容易忘记写close()异常处理代码冗余多个资源时嵌套很深使用with后withopen(test.txt,r,encodingutf-8)asf:dataf.read()# 到这里文件已经自动关闭即使中间发生异常也会关闭二、基本语法with表达式as变量:# 使用资源...# 离开 with 代码块后资源自动清理表达式必须返回一个上下文管理器对象as 变量是可选的用来接收__enter__方法的返回值常见例子# 文件withopen(data.txt,w,encodingutf-8)asf:f.write(hello)# 多个文件Python 3.10 支持括号换行with(open(a.txt)asf1,open(b.txt)asf2):...三、上下文管理器协议一个对象只要实现了以下两个方法就可以成为上下文管理器classMyContext:def__enter__(self):进入 with 代码块时调用print(获取资源)returnself# 返回值会赋给 as 后面的变量def__exit__(self,exc_type,exc_val,exc_tb):离开 with 代码块时调用无论是否发生异常print(释放资源)# 返回 True 表示异常已被处理不再向外抛出# 返回 False 或 None 表示异常继续向外抛出returnFalse使用withMyContext()asobj:print(在 with 内部)# 如果这里发生异常__exit__ 依然会被调用执行顺序调用__enter__执行with代码块调用__exit__即使发生异常也会调用四、自定义上下文管理器的两种方式1. 基于类的实现classTimer:def__enter__(self):importtime self.starttime.perf_counter()returnselfdef__exit__(self,exc_type,exc_val,exc_tb):importtime self.elapsedtime.perf_counter()-self.startprint(f耗时{self.elapsed:.4f}秒)returnFalse# 不吞掉异常withTimer():# 做一些耗时操作sum(range(1000000))2. 基于生成器的实现推荐更简洁使用contextlib.contextmanager装饰器fromcontextlibimportcontextmanagerimporttimecontextmanagerdeftimer():starttime.perf_counter()try:yield# yield 之前的代码相当于 __enter__# yield 的值会赋给 as 后面的变量finally:elapsedtime.perf_counter()-startprint(f耗时{elapsed:.4f}秒)withtimer():sum(range(1000000))带返回值的例子contextmanagerdefopen_file(path,moder):fopen(path,mode,encodingutf-8)try:yieldffinally:f.close()withopen_file(test.txt)asf:print(f.read())五、__exit__的三个参数def__exit__(self,exc_type,exc_val,exc_tb):...参数含义无异常时exc_type异常类如ValueErrorNoneexc_val异常实例Noneexc_tbtraceback 对象None如果__exit__返回True异常会被“吞掉”返回False或None则继续向外抛出。def__exit__(self,exc_type,exc_val,exc_tb):ifexc_typeisnotNone:print(f发生异常{exc_val})returnTrue# 吞掉异常程序继续执行六、常见实际应用场景文件操作最经典数据库连接 / 事务线程锁临时修改系统状态如当前目录、环境变量计时、日志、性能监控网络连接测试中的 mock 环境示例临时切换目录fromcontextlibimportcontextmanagerimportoscontextmanagerdefchange_dir(path):old_diros.getcwd()os.chdir(path)try:yieldfinally:os.chdir(old_dir)withchange_dir(/tmp):print(os.getcwd())# /tmp# 自动恢复原来的目录七、contextlib常用工具fromcontextlibimportcontextmanager,suppress,redirect_stdout,ExitStack工具作用contextmanager用生成器快速创建上下文管理器suppress忽略指定异常redirect_stdout临时重定向标准输出ExitStack动态管理多个上下文管理器nullcontext空的上下文管理器占位用忽略异常示例fromcontextlibimportsuppresswithsuppress(FileNotFoundError):os.remove(不存在的文件.txt)# 文件不存在也不会报错八、最佳实践优先使用with管理资源文件、连接、锁等需要自定义时优先用contextmanager代码更少__exit__中尽量做好清理不要轻易吞掉异常多个资源可以用嵌套with或ExitStack不要在__enter__/__exit__里写过于复杂的业务逻辑 感谢阅读想了解更多 我的博客网站 | 记录思考分享干货 我的个人主页 | 关于我、开源项目

相关新闻

CIMPro孪大师|智能制造企业数字孪生展示平台建设方案

CIMPro孪大师|智能制造企业数字孪生展示平台建设方案

1 行业现存痛点园区、车间、产线结构复杂,洁净/精密生产区域不便对外开放,线下参观门槛高;产线工艺、设备原理依赖二维图纸讲解,客户与新员工理解成本高,展示效果弱;设备运维培训以老师傅带教为主&#xff…

2026/11/13 12:02:13 阅读更多 →
深耕劳务行业五年,我观察到的湖南劳务外包市场真实现状

深耕劳务行业五年,我观察到的湖南劳务外包市场真实现状

做劳务外包这行满五年,跑遍了湖南大大小小的产业园、物流园还有县域农业基地,见过太多企业在用工上踩的坑,也摸透了本地劳务市场的真实家底。很多人觉得劳务外包就是“找临时工”,其实这两年湖南市场的需求早就变了。首先是合规压…

2026/11/13 12:02:13 阅读更多 →
离散傅里叶变换DFT代码解析

离散傅里叶变换DFT代码解析

摘要:本文通过Excel模拟1024点采样数据,演示FFT与DFT计算原理,并给出STM32嵌入式DFT实现,涵盖各次谐波幅值相位、频率分辨率、电压电流相角差以及有功无功功率的计算方法。 1、FFT理解 关于FFT的理解摘录自:傅里叶变换FFT(基于Excel) 1)数据产生 利用Excel模拟出一…

2026/11/3 13:38:51 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/13 5:13:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/13 5:13:25 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/13 5:13:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/12 18:22:26 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/13 5:13:25 阅读更多 →

日新闻

周新闻

月新闻