大多数教程展示了平凡的 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} 秒")

为什么这很重要

  • 自动计时代码块
  • 即使在异常情况下也会报告时间
  • 便于性能监控

关键要点

  1. 上下文管理器不仅仅用于文件 - 它们适用于任何需要设置/清理的资源
  2. 异常安全 - __exit__ 方法总是被调用,即使在异常情况下
  3. 可组合 - 您可以嵌套多个上下文管理器
  4. 可重用 - 创建一次,使用多次

实际应用

这些模式在实际代码中非常有用,特别是当您处理数据库连接、临时文件、网络连接或需要精确计时的操作时。

记住:上下文管理器是Python中资源管理的瑞士军刀。学习使用它们将使您的代码更健壮和更易维护。