为 with语句上下文提供的工具
contextlib — Utilities for with-statement contexts — Python 3.14.6 documentation
def contextmanager(func):
"""@contextmanager decorator.
Typical usage:
@contextmanager
def some_generator(<arguments>):
<setup>
try:
yield <value>
finally:
<cleanup>
This makes this:
with some_generator(<arguments>) as <variable>:
<body>
equivalent to this:
<setup>
try:
<variable> = <value>
<body>
finally:
<cleanup>
"""
@wraps(func)
def helper(*args, **kwds):
return _GeneratorContextManager(func, args, kwds)
return helper
- @contextlib.contextmanager
-
此函数是一个 decorator,它可被用来定义一个支持
with语句上下文管理器的工厂函数,而无需创建一个类或单独的__enter__()和__exit__()方法。尽管许多对象都原生支持在 with 语句中使用,但有时需要被管理的资源本身并不是上下文管理器,并且没有实现
close()方法以配合contextlib.closing使用。下面是一个抽象的示例,展示如何确保正确的资源管理:
from contextlib import contextmanager @contextmanager def managed_resource(*args, **kwds): # 获取资源的代码,例如: resource = acquire_resource(*args, **kwds) try: yield resource finally: # 释放资源的代码,例如: release_resource(resource)随后可以这样使用此函数:
with managed_resource(timeout=3600) as resource: # 资源将在此代码块的末尾被释放, # 即使代码块中的代码引发了异常被装饰的函数在被调用时,必须返回一个 generator 迭代器。 这个迭代器必须只 yield 一个值出来,这个值会被用在
with语句中,绑定到as后面的变量,如果给定了的话。当生成器发生 yield 时,嵌套在
with语句中的语句体会被执行。 语句体执行完毕离开之后,该生成器将被恢复执行。 如果在该语句体中发生了未处理的异常,则该异常会在生成器发生 yield 时重新被引发。 因此,你可以使用try...except...finally语句来捕获该异常(如果有的话),或确保进行了一些清理。 如果仅出于记录日志或执行某些操作(而非完全抑制异常)的目的捕获了异常,生成器必须重新引发该异常。 否则生成器的上下文管理器将向with语句指示该异常已经被处理,程序将立即在with语句之后恢复并继续执行。contextmanager()使用ContextDecorator因此它创建的上下文管理器不仅可以用在with语句中,还可以用作一个装饰器。当它用作一个装饰器时,每一次函数调用时都会隐式创建一个新的生成器实例(这使得contextmanager()创建的上下文管理器满足了支持多次调用以用作装饰器的需求,而非“一次性”的上下文管理器)。

浙公网安备 33010602011771号