
在Python编程中上下文管理器Context Manager是一个强大而优雅的特性。它通过with语句实现了资源的自动获取和释放让代码更加简洁、可读性更强同时有效避免了资源泄漏问题。本文将深入探讨上下文管理器的工作原理、实现方式以及实际应用场景。 为什么需要上下文管理器在没有上下文管理器之前我们处理文件操作通常是这种方式# 传统方式 - 容易出错 f open(data.txt, r) data f.read() f.close() # 如果上面出错这里不会执行使用try-finally改进# try-finally 方式 - 代码冗长 f open(data.txt, r) try: data f.read() finally: f.close() # 确保关闭但代码繁琐而使用with语句# with 语句 - 简洁优雅 with open(data.txt, r) as f: data f.read() # 自动关闭无需手动处理⚙️ 上下文管理器的工作原理上下文管理器的核心是两个特殊方法__enter__(): 进入上下文时调用返回的资源会赋值给as后的变量__exit__(exc_type, exc_val, exc_tb): 退出上下文时调用处理异常清理工作️ 自定义上下文管理器方式一基于类的实现class DatabaseConnection: def __init__(self, host, port): self.host host self.port port self.connection None def __enter__(self): print(f 连接到数据库 {self.host}:{self.port}) self.connection fConnection({self.host}:{self.port}) return self.connection def __exit__(self, exc_type, exc_val, exc_tb): print(f 关闭数据库连接) self.connection None # 返回True表示异常已被处理不再传播 return False # 使用示例 with DatabaseConnection(localhost, 3306) as conn: print(f执行查询: {conn}) # 输出 # 连接到数据库 localhost:3306 # 执行查询: Connection(localhost:3306) # 关闭数据库连接方式二使用 contextlib 装饰器更简洁from contextlib import contextmanager contextmanager def managed_resource(name): print(f 获取资源: {name}) resource fResource({name}) try: yield resource # 这里是 with 语句 as 变量的值 finally: print(f️ 释放资源: {name}) # 使用示例 with managed_resource(file_handle) as res: print(f使用: {res}) # 输出 # 获取资源: file_handle # 使用: Resource(file_handle) # ️ 释放资源: file_handle 实际应用场景1. 数据库事务管理from contextlib import contextmanager contextmanager def transaction(conn): try: conn.begin() yield conn conn.commit() print(✅ 事务提交成功) except Exception as e: conn.rollback() print(f❌ 事务回滚: {e}) raise # 使用 with transaction(db_conn) as conn: conn.execute(INSERT INTO users VALUES (1, Alice)) conn.execute(INSERT INTO orders VALUES (1, 100))2. 性能计时器import time from contextlib import contextmanager contextmanager def timer(label): start time.time() try: yield finally: elapsed time.time() - start print(f⏱️ {label}: {elapsed:.4f}秒) # 使用 with timer(数据处理): result sum(range(1000000)) # 输出⏱️ 数据处理: 0.0234秒3. 临时修改环境import os from contextlib import contextmanager contextmanager def temporary_env(key, value): old_value os.environ.get(key) os.environ[key] value try: yield finally: if old_value is None: del os.environ[key] else: os.environ[key] old_value # 使用 with temporary_env(DEBUG, 1): print(fDEBUG {os.environ.get(DEBUG)}) # DEBUG 1 print(fDEBUG {os.environ.get(DEBUG)}) # 恢复原值 嵌套上下文管理器Python支持同时管理多个上下文# 同时打开多个文件 with open(input.txt) as fin, open(output.txt, w) as fout: for line in fin: fout.write(line.upper()) # 等价于嵌套写法 with open(input.txt) as fin: with open(output.txt, w) as fout: for line in fin: fout.write(line.upper())