跳至主要內容

python上下文管理器和with

pptg大约 3 分钟

1. 什么是上下文管理器

上下文管理器(Context Manager)是Python中用于管理资源(如文件、数据库连接、锁等)的对象,它定义了在进入和退出代码块时要执行的操作。上下文管理器通过实现 __enter__()__exit__() 方法来工作

2. with的作用

with语句提供了一种优雅的方式来管理资源,确保资源被正确初始化和清理,即使在发生异常的情况下也是如此。它的主要优势包括:

  • 自动资源管理:自动获取和释放资源
  • 异常安全:即使在with块内发生异常,清理代码也会被执行
  • 代码简洁:避免了冗长的try...finally
  • 可读性强:清晰地标出了资源的作用范围

with的工作原理:

  • 调用上下文管理器的__enter__()方法
  • __enter__()的返回值赋值给as后面的变量
  • 执行with块内的代码
  • 无论块内代码是否发生异常,都会调用__exit__()方法进行清理
自定义上下文管理器类
# 自定义上下文管理器 - 类方式
class Timer:
    """测量代码执行时间的上下文管理器"""
    
    def __init__(self, name="Operation"):
        self.name = name
    
    def __enter__(self):
        import time
        self.start = time.time()
        print(f"开始: {self.name}")
        return self  # 这个返回值会赋值给as后面的变量
    
    def __exit__(self, exc_type, exc_value, traceback):
        import time
        self.end = time.time()
        self.duration = self.end - self.start
        print(f"⏰ 结束: {self.name}, 耗时: {self.duration:.4f}秒")
        # 返回False让异常继续传播,返回True则抑制异常
        return False

# 使用自定义的Timer上下文管理器
def expensive_operation():
    with Timer("昂贵的计算"):
        import time
        time.sleep(1)  # 模拟耗时操作
        result = sum(i * i for i in range(10000))
    return result

3. 什么时候应该使用上下文管理器?

主要在这些场景下使用:

  • 资源管理:文件、网络连接、数据库连接等需要关闭的资源
  • 锁的获取和释放:确保线程安全
  • 事务管理:数据库事务的开始、提交和回滚
  • 临时状态修改:需要临时改变某些设置,之后自动恢复
  • 计时和性能分析:测量代码块的执行时间

4. contextlib.contextmanager装饰器是如何工作的?

这个装饰器将生成器函数转换为上下文管理器。生成器必须只yield一次:

  • yield之前的代码相当于__enter__()方法
  • yield的值相当于__enter__()的返回值
  • yield之后的代码相当于__exit__()方法,放在finally块中确保执行