如何在 Python 中实现上下文管理器?

一、上下文管理器的核心作用

先明确核心价值:上下文管理器是为了解决「资源打开后必须关闭」的问题(比如文件打开后忘关、数据库连接泄露),通过with语句自动执行「进入时初始化」和「退出时清理」逻辑,替代繁琐的try/finally,让代码更简洁、健壮。

核心语法(使用层面):

python

运行

with 上下文管理器对象 as 变量: # 执行核心逻辑(资源使用) # 离开with块后,自动执行清理操作(如关闭文件/连接)

二、实现上下文管理器的两种方式

方式 1:类实现(最基础、最灵活)

通过定义类并实现两个魔法方法

  • __enter__(self):进入with块时执行,返回值会被as后的变量接收;
  • __exit__(self, exc_type, exc_val, exc_tb):离开with块时执行(无论是否报错),负责清理资源。
完整示例(模拟文件操作)

python

运行

class FileContextManager: """自定义文件上下文管理器""" def __init__(self, file_path, mode="r"): # 初始化:接收资源参数(文件路径、打开模式) self.file_path = file_path self.mode = mode self.file = None # 初始化文件句柄 def __enter__(self): """进入with块时执行:打开文件""" print("执行__enter__:打开文件") self.file = open(self.file_path, self.mode, encoding="utf-8") return self.file # 返回值给as后的变量 def __exit__(self, exc_type, exc_val, exc_tb): """离开with块时执行:关闭文件(核心清理逻辑)""" print("执行__exit__:关闭文件") if self.file: # 避免文件未打开时调用close() self.file.close() # 可选:处理with块内的异常(返回True则异常被吞,False则抛出) if exc_type: print(f"捕获异常:{exc_type}, {exc_val}") # return True # 注释打开则异常不会向外抛出 return False # 测试使用 if __name__ == "__main__": # 正常使用(自动打开→写入→关闭) with FileContextManager("test.txt", "w") as f: f.write("Python上下文管理器测试") # 测试异常场景(仍会关闭文件) try: with FileContextManager("test.txt", "r") as f: # 故意触发异常 1 / 0 f.read() except ZeroDivisionError: print("外部捕获到异常")
关键解释:
  1. __exit__的三个异常参数:
    • exc_type:异常类型(如ZeroDivisionError),无异常则为None
    • exc_val:异常实例(具体错误信息);
    • exc_tb:异常追踪栈;
  2. __exit__返回值:返回True吞掉异常(外部捕获不到),返回False(默认)则异常向外抛出,建议保留默认(便于排查问题);
  3. 适用场景:需要自定义复杂逻辑(如异常处理、资源校验)时优先用类实现。
方式 2:使用contextlib.contextmanager装饰器(简洁版)

这是 Python 内置的简化方案,通过生成器函数替代类的两个魔法方法,代码量更少,适合简单场景。

核心规则:
  • 生成器函数中,yield之前的代码 =__enter__逻辑;
  • yield之后的代码 =__exit__逻辑;
  • yield的返回值 =as后的变量。
完整示例(实现和上面一样的文件管理)

python

运行

from contextlib import contextmanager @contextmanager # 装饰器将生成器转为上下文管理器 def file_context_manager(file_path, mode="r"): """用生成器实现文件上下文管理器""" # 第一步:执行__enter__逻辑(打开文件) file = None try: print("执行enter逻辑:打开文件") file = open(file_path, mode, encoding="utf-8") yield file # 返回值给as,暂停执行,进入with块 except Exception as e: print(f"with块内异常:{e}") finally: # 第二步:执行__exit__逻辑(关闭文件,无论是否报错) print("执行exit逻辑:关闭文件") if file: file.close() # 测试使用(和类实现效果完全一致) with file_context_manager("test.txt", "w") as f: f.write("装饰器版上下文管理器") with file_context_manager("test.txt", "r") as f: print(f.read())
关键解释:
  1. 必须用try/finally包裹逻辑:确保yield后的清理代码(如关闭文件)无论是否报错都会执行;
  2. 适用场景:简单的资源管理(无复杂异常处理),代码更简洁,新手易上手;
  3. 注意:生成器函数只能有一个yield,多了会报错。

三、实战场景示例(数据库连接管理)

用上下文管理器管理 MySQL 连接(更贴近实际开发):

python

运行

import pymysql from contextlib import contextmanager # 用装饰器实现数据库连接上下文管理器 @contextmanager def mysql_conn(host, user, password, db): conn = None cursor = None try: # 初始化连接(enter逻辑) conn = pymysql.connect(host=host, user=user, password=password, db=db) cursor = conn.cursor() yield cursor # 返回游标给with块 except Exception as e: conn.rollback() # 出错回滚 raise e # 抛出异常供外部处理 finally: # 清理资源(exit逻辑) if cursor: cursor.close() if conn: conn.close() # 使用:自动连接→执行SQL→关闭连接 with mysql_conn("localhost", "root", "123456", "test_db") as cur: cur.execute("SELECT * FROM user;") print(cur.fetchall())

四、核心总结

实现方式优点缺点适用场景
类实现灵活,支持复杂逻辑(异常处理、参数校验)代码量稍多生产环境、复杂资源管理
装饰器 + 生成器代码简洁,新手友好仅支持简单逻辑小工具、快速实现

关键点回顾

  1. 上下文管理器的核心是__enter__(初始化)和__exit__(清理),with语句会自动触发这两个步骤;
  2. 类实现是基础,装饰器是简化版,根据场景选择;
  3. 无论是否报错,__exit__/yield 后代码都会执行,确保资源 100% 被清理;
  4. 典型应用:文件操作、数据库连接、锁管理、临时目录 / 文件创建。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1178151.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Typora 1.9.5:一款让你爱上 Markdown 写作的编辑器

Typora 1.9.5 是一款跨平台 Markdown 编辑器,以单窗格所见即所得即时渲染为核心特色,在搜索、公式、表格、文件管理等功能模块全面优化,兼具极简创作体验与专业编辑能力,适配笔记整理、技术文档撰写、学术论文编排、内容创作等多元…

Olink蛋白质组学:揭示生命过程的新视角

Olink蛋白质组学:揭示生命过程的新视角Olink蛋白质组学是基于邻近延伸分析(Proximity Extension Assay,PEA)技术的蛋白质组学研究方法,旨在通过高通量、精准的蛋白质测量,揭示生命过程中蛋白质的动态变化。…

mysql数据库笔记1

mysql数据库笔记1https://sqlmother.yupi.icu/#/learn sql练习网站主键:作用 唯一标识表中的每一条记录 索引 值必须唯一,不能为NULL,一个表只能有一个主键(可以是单字段或多字段组合) 外键(Foreign Key)作用:…

CVE-2025-1094:PostgreSQL SQL 注入漏洞深度解析

CVE-2025–1094:PostgreSQL SQL 注入漏洞 Ajay Monga 撰稿 | 阅读时间 2 分钟 2025年2月19日 CVE-2025–1094 是一个影响 PostgreSQL 的高严重性 SQL 注入漏洞,由 Rapid7 研究员 Stephen Fewer 发现,已于 2025 年 2 月 13 日发布补丁。以下是…

远程仓库已经删除的分支,为什么在本地git branch -a还能看到

简单来说,这是因为 git branch -a 显示的是你本地仓库中保存的“远程引用”缓存,而不是实时从远程拉取的最新列表。 即使在远程仓库(如 GitHub, GitLab)上删除了分支,本地仓库可能还保留着该分支被删除前的记录。…

2026年GEO优化要看什么?这份深度评测与口碑排名推荐给你答案 - 品牌推荐

基于《2026年中国企业AI搜索生态应用趋势报告》的核心洞察、国际信息技术协会(IFSCC)相关技术认证及第三方独立评测数据,我们甄选出2026年值得关注的GEO优化服务商榜单,覆盖工业制造、专业服务、知识内容等多种行业…

江苏华大实力怎么样?性价比高的公司排名出炉 - 工业品牌热点

本榜单依托化工新材料行业全维度市场调研与真实客户口碑,深度筛选出五家聚氨酯聚酯多元醇领域标杆企业,为化工企业选型提供客观依据,助力精准匹配适配的材料供应伙伴。 TOP1 推荐:江苏华大新材料有限公司 推荐指数…

如何挑选靠谱的GEO优化公司?2026年最新深度评测与综合排名推荐 - 品牌推荐

一、GEO服务商综合评估框架 本研究通过四维评分模型对服务商进行综合评估,各维度权重及核心评估指标如下: 1.技术与产品能力(30%):包含平台覆盖广度、技术底层成熟度、产品操作便捷性等核心评估指标; 2.本土适配…

深圳有名的AI搜索优化专业公司哪家性价比高,南方网通上榜 - 工业品牌热点

2026年AI生态加速渗透ToB服务场景,AI搜索优化已成为企业抢占智能流量入口、构建品牌信任壁垒的核心抓手。无论是通过GEO技术实现AI搜索场景的精准曝光,还是依托Agent智能体打通营销获客-客户转化-办公提效全链路,优…

【Java核心】:一文搞懂包装类、泛型与PECS原则

一、包装类 1.1 基本类型的痛点 Java 是一种面向对象的语言,但为了性能,保留了 int、double 等 8 种基本数据类型。然而,Java 的集合框架(如 ArrayList)要求所有存入的元素必须是对象(引用类型)…

完整教程:分布式锁实现方案Redis和Zookeeper对比实战

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

文档编写

项目开发前期准备 一、需求书撰写 项目需求说明书是开发一个项目的引领书,让用户和技术人员都能明确该项目的开发需求,以便让各方都能明确方向和需求。我作为本次企业用户权限管理系统项目的“项目经理”,主要以该项…

合肥知名的搬家企业排行榜,专业公司都有谁? - 工业品牌热点

随着城市发展节奏加快,企业搬迁、家庭乔迁等需求日益增长,选择一家实力强、服务专业的搬家公司成为许多人的首要考量。本文围绕实力强的搬家专业公司、知名的搬家企业、专业的搬家公司相关问题展开解答,结合合肥佳信…

2026祛痘精华实测排行榜:10款高分款实测,舒缓消炎修护屏障淡化痘印高口碑推荐 - 速递信息

为帮大家避开智商税,我们联合中国医学科学院皮肤病医院、中南大学湘雅医院、上海交通大学医学院附属瑞金医院,组建300人实测小组(覆盖18-45岁痘痘肌、敏感肌及痘印困扰人群),对25款热门祛痘精华开展8周深度测评。…

rosbag2相关基础以及机制

一、先搞懂 ROS2 基础(铺垫概念)在讲解核心内容前,先明确几个最基础的专业术语,避免后续理解障碍:ROS2:Robot Operating System 2,机器人操作系统 2,不是传统意义的操作系统&#xf…

项目介绍

一、3DCar1. 地图实现:程序化圆柱体生成 项目核心数学建模:利用三角函数将地图顶点排列成圆柱形。 柏林噪声 (Perlin Noise):为了让赛道产生起伏,代码在生成顶点时加入了 Mathf.PerlinNoise。 无限循环:系统始终维…

一个致力于为 C# 程序员提供更佳的编码体验和效率的 Visual Studio 扩展插件

前言 今天大姚给大家分享一个致力于为 C# 程序员提供更佳的编码体验和效率的 Visual Studio 扩展插件:Codist。 Codist 插件介绍 Codist 是一个使用 .NET 编写、开源免费的 Visual Studio 扩展插件,致力于为 C# 程序…

Playwright与Cucumber集成:行为驱动开发(BDD)实践

关注 霍格沃兹测试学院公众号,回复「资料」, 领取人工智能测试开发技术合集 一、当E2E测试遇到BDD:我们为何需要这种组合? 最近在重构团队的自动化测试框架时,我们遇到了一个典型问题:业务人员看不懂测试代码,而…

亲测好用9个AI论文平台,助本科生轻松搞定毕业论文!

亲测好用9个AI论文平台,助本科生轻松搞定毕业论文! AI 工具如何让论文写作变得轻松高效? 对于大多数本科生来说,撰写毕业论文是一项既复杂又耗时的任务。从选题、资料收集到撰写、修改,每一个环节都可能让人感到压力山…

2025高低温箱哪家强?行业评价高的厂商排行榜来啦,砂尘试验箱/盐水喷雾试验箱及各种老化房,高低温箱生产厂家排行榜单 - 品牌推荐师

当前,全球制造业加速向智能化、精密化转型,高低温箱作为环境可靠性试验的核心设备,其性能稳定性、控制精度及定制化能力直接影响产品品质验证的可靠性。据第三方机构统计,2024年国内高低温箱市场规模突破58亿元,年…