大多数教程展示了平凡的 with open(...) 示例,然后就停止了。这里是我在实际代码中实际使用的三个模式,以及每个模式防止的故障模式。
案例1:资源清理与错误处理
当您有必须清理的资源时,无论发生什么:
class DatabaseConnection:
def __init__(self, config):
self.config = config
self.connection = None
def __enter__(self):
self.connection = create_connection(self.config)
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
if self.connection:
self.connection.close()
为什么这很重要
- 即使在异常情况下也会清理资源
- 防止资源泄漏
- 使代码更可靠
案例2:临时状态管理
当您需要临时更改某些状态,然后恢复它:
class TempDir:
def __init__(self, base_path="/tmp"):
self.base_path = base_path
self.temp_path = None
def __enter__(self):
import tempfile
self.temp_path = tempfile.mkdtemp(dir=self.base_path)
return self.temp_path
def __exit__(self, exc_type, exc_val, exc_tb):
import shutil
if self.temp_path and os.path.exists(self.temp_path):
shutil.rmtree(self.temp_path)
为什么这很重要
- 自动清理临时文件
- 防止磁盘空间浪费
- 简化错误处理
案例3:性能监控和计时
当您需要测量代码执行时间:
import time
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
print(f"执行时间: {self.end - self.start:.2f} 秒")
为什么这很重要
- 自动计时代码块
- 即使在异常情况下也会报告时间
- 便于性能监控
关键要点
- 上下文管理器不仅仅用于文件 - 它们适用于任何需要设置/清理的资源
- 异常安全 -
__exit__方法总是被调用,即使在异常情况下 - 可组合 - 您可以嵌套多个上下文管理器
- 可重用 - 创建一次,使用多次
实际应用
这些模式在实际代码中非常有用,特别是当您处理数据库连接、临时文件、网络连接或需要精确计时的操作时。
记住:上下文管理器是Python中资源管理的瑞士军刀。学习使用它们将使您的代码更健壮和更易维护。