Python - 上下文管理器



Python 中的上下文管理器提供了一种强大且安全的方式来有效管理资源。Python 中的上下文管理器是一个对象,它定义了一个与with语句一起使用的运行时上下文。它确保自动执行设置和清理操作。

例如,在处理文件操作时,上下文管理器会处理文件的打开和关闭,确保正确管理资源。

上下文管理器的工作原理?

Python 上下文管理器通过实现__enter__()__exit__()方法(或异步操作的异步等效方法)来工作。这些方法确保正确获取和释放资源。此外,Python 的contextlib模块进一步简化了自定义上下文管理器的创建。

示例

以下是一个简单的示例,演示了上下文管理器如何在 Python 中与文件操作一起工作。

with open('example.txt', 'w') as file:
    file.write('Hello, Tutorialspoint!')

在此示例中,文件以写入模式打开,然后在退出with语句内的代码块时自动关闭。

Python 上下文管理器类型

Python 支持同步和异步上下文管理器。每种类型都有需要实现的特定方法来管理上下文的生命周期。

同步上下文管理器

同步上下文管理器使用__enter__()__exit__()方法实现。

1. __enter__() 方法

当执行进入 with 语句的上下文时,将调用__enter__(self)方法。此方法应返回要在 with 代码块内使用的资源。

示例

以下是如何使用__enter__()__exit__()方法创建我们自己的上下文管理器的简单示例。

class MyContextManager:
   def __enter__(self):
      print("Entering the context")
      return self

   def __exit__(self, exc_type, exc_value, traceback):
      print("Exiting the context")
        
with MyContextManager():
   print("body")

执行以上代码,您将得到以下输出 -

Entering the context
body
Exiting the context

2. __exit__() 方法

__exit__(self, exc_type, exc_value, traceback) 方法在执行离开 with 语句上下文时被调用。它可以处理任何发生的异常,并返回一个布尔标志,指示是否应该抑制异常。

此示例演示了如何创建我们自己的上下文管理器以及 __exit__() 方法如何处理异常。

class MyContextManager:
   def __enter__(self):
      print("Entering the context")
      return self

   def __exit__(self, exc_type, exc_value, traceback):
      print("Exiting the context")
      if exc_type:
         print("An exception occurred")
      return True  # Suppress exception

with MyContextManager():
   print("body")
   name =  "Python"/3 #to raise an exception

在执行以上代码时,您将获得以下输出 -

Entering the context
body
Exiting the context
An exception occurred

异步上下文管理器

与同步上下文管理器类似,异步上下文管理器也使用两个方法实现,即 __aenter__()__aexit__()。这些用于async with 语句中。

__aenter__(self) 方法 - 它必须返回一个可等待对象,当进入上下文时将被等待。

__aexit__(self, exc_type, exc_value, traceback) 方法 - 它必须返回一个可等待对象,当退出上下文时将被等待。

示例

以下是创建异步上下文管理器类的示例 -

import asyncio
class AsyncContextManager:
   async def __aenter__(self):
      print("Entering the async context class")
      return self

   async def __aexit__(self, exc_type, exc_value, traceback):
      print("Exiting the async context class")
      if exc_type:
         print("Exception occurred")
      return True

async def main():
   async with AsyncContextManager():
      print("Inside the async context")
      name =  "Python"/3 #to raise an exception

asyncio.run(main())

执行以上代码,您将获得以下输出 -

Entering the async context class
Inside the async context
Exiting the async context class
Exception occurred

创建自定义上下文管理器

Python 标准库中的contextlib 模块提供了更轻松地创建上下文管理器的实用程序。

使用 contextlib.contextmanager() 函数

contextlib.contextmanager() 函数是一个装饰器,允许您为 with 语句上下文管理器创建工厂函数。它消除了定义单独的类或分别实现__enter__()__exit__() 方法的需要。

示例

这是一个使用 contextlib.contextmanager 创建上下文管理器函数的示例。

from contextlib import contextmanager

@contextmanager
def my_context_manager():
   print("Entering the context manager method")
   try:
      yield
   finally:
      print("Exiting the context manager method")

with my_context_manager():
   print("Inside the context")

执行以上代码,您将获得以下输出 -

Entering the context manager method
Inside the context
Exiting the context manager method

使用 contextlib.asynccontextmanager() 函数

contextlib 模块还提供 asynccontextmanager,专门用于创建异步上下文管理器。它类似于 contextmanager,并且消除了定义单独的类或分别实现__aenter__()__aexit__() 方法的需要。

示例

这是一个演示使用 contextlib.asynccontextmanager() 创建异步上下文管理器函数的示例。

import asyncio
from contextlib import asynccontextmanager

@asynccontextmanager
async def async_context_manager():
   try:
      print("Entering the async context")
      # Perform async setup tasks if needed
      yield
   finally:
      # Perform async cleanup tasks if needed
      print("Exiting the async context")

async def main():
   async with async_context_manager():  
      print("Inside the async context")
      await asyncio.sleep(1)  # Simulating an async operation

# Run the asyncio event loop
asyncio.run(main())

执行以上代码,您将获得以下输出 -

Entering the async context
Inside the async context
Exiting the async context
广告