
__enter__(self):在进入上下文时执行的代码。__exit__(self, exc_type, exc_value, traceback):在退出上下文时执行的代码。with open('file.txt', 'r') as file:
data = file.read()
其工作流程如下:
__enter__ 方法。__enter__ 方法的返回值赋给 as 后面的变量(如上例中的 file)。__exit__ 方法。当使用with语句时,首先会调用上下文管理器的__enter__()方法。这通常包括一些预处理操作,如打开文件、获取锁等。
在with语句的代码块内执行用户定义的操作。这些操作可以是任何Python代码。
当代码块执行完毕后,会自动调用上下文管理器的__exit__()方法。这通常包括一些清理操作,如关闭文件、释放锁等。
要实现一个上下文管理器,可以通过以下两种方式:
可以通过实现 __enter__ 和 __exit__ 方法来自定义上下文管理器。例如:
class MyContextManager: def __enter__(self): print("进入自定义上下文管理器") return self def __exit__(self, exc_type, exc_value, traceback): print("退出上下文管理器") if exc_type is not None: print(f"Exception: {exc_type}, {exc_value}") return True # Suppress the exception # 使用自定义的上下文管理器 with MyContextManager() as manager: print("在上下文管理器中") raise ValueError("发送错误!")'运行
输出为:

Python 提供了 contextlib 模块,帮助简化上下文管理器的创建。特别是contextlib.contextmanager装饰器,可以将一个生成器函数转换为上下文管理器
from contextlib import contextmanager @contextmanager def my_context(): print("进入上下文(装饰器)") try: yield finally: print("退出上下文管理器(装饰器)") # 使用生成器函数作为上下文管理器 with my_context(): print("在上下文管理器中(装饰器)")'运行
输出为:

yield是一个关键字,用于实现生成器函数。生成器函数是一种特殊的函数,它返回一个生成器对象,这个对象支持迭代协议,即它有__iter__()和__next__()方法。生成器允许你在每次迭代时按需生成值,而不是一次性生成所有值,这有助于节省内存和提高性能。
想象你有一个工厂,这个工厂生产水果。但是,你不想一次性生产出所有的水果,因为你没有足够的地方来存放它们。你希望按照需求生产,每次只生产一个水果,当有人需要时才生产下一个。
在Python中,yield就像是这个工厂的生产线。当你定义一个函数时,如果函数里面包含了yield,这个函数就变成了一个生成器函数。每次你调用这个生成器函数,它都会给你一个水果,然后停下来,等待下一次请求。
def fruit_factory(): yield "苹果" yield "香蕉" yield "橙子" factory = fruit_factory() print(next(factory)) # 输出 "苹果" print(next(factory)) # 输出 "香蕉" print(next(factory)) # 输出 "橙子"'运行

在Python中,
@contextmanager是一个装饰器,位于contextlib模块下。它的主要作用是将一个生成器函数转换为一个上下文管理器,从而可以使用with语句来管理代码块的上下文。使用@contextmanager装饰器,可以简化创建上下文管理器的过程,避免手动编写__enter__和__exit__方法。
上下文管理器还可以处理异常。在with语句中,如果发生异常,上下文管理器的__exit__()方法会被调用,以确保资源的正确释放,即使在异常情况下也能保证资源的安全性。