大锤python日记(实现上下文管理器的两种方式)

79 阅读2分钟

在Python中,创建上下文管理器的方式有两种:使用类实现上下文管理器和使用生成器实现上下文管理器。

  1. 使用类实现上下文管理器

使用类实现上下文管理器是最常见的方式。我们可以定义一个类,并在类中实现__enter__()__exit__()方法来实现上下文管理器。__enter__()方法用于进入上下文环境,__exit__()方法用于离开上下文环境并清理资源。

下面是一个简单的示例,演示了如何使用类实现上下文管理器:

class MyContextManager:
    def __init__(self, resource):
        self.resource = resource

    def __enter__(self):
        print("Entering context...")
        return self.resource

    def __exit__(self, exc_type, exc_val, traceback):
        print("Leaving context...")
        if exc_type is not None:
            print(f"An error occurred: {exc_type} - {exc_val}")
        return False   # 指示不需要重新抛出异常

# 创建一个上下文管理器对象
my_context_manager = MyContextManager("resource")

# 使用 with 语句进入上下文环境
with my_context_manager as resource:
    print(f"Resource: {resource}")

# 离开上下文环境
print("Context exited.")
  1. 使用生成器实现上下文管理器

使用生成器实现上下文管理器是一种更为简洁的方式,它涉及到contextlib模块中的contextmanager()函数。我们可以使用contextmanager()函数来定义一个生成器,并在生成器中使用yield语句将控制权传递给上下文环境。当执行完毕后,生成器会自动回到yield语句之后的代码块,并执行清理操作。

下面是一个简单的示例,演示了如何使用生成器实现上下文管理器:

from contextlib import contextmanager

@contextmanager
def my_context_manager(resource):
    print("Entering context...")
    try:
        yield resource   # 将控制权交给 with 语句块
    except Exception as e:
        print(f"An error occurred: {e}")
    finally:
        print("Leaving context...")

# 使用 with 语句进入上下文环境
with my_context_manager("resource") as resource:
    print(f"Resource: {resource}")

# 离开上下文环境
print("Context exited.")

以上两种方式都能够实现上下文管理器,具体使用哪种方式取决于情况和个人偏好。通常情况下,如果实现较为复杂或需要维护一些状态,使用类实现上下文管理器会更加方便;而如果实现比较简单,使用生成器实现上下文管理器可能会更优雅。