发送到使用contextlib.contextmanager定义的上下文管理器

时间:2013-05-15 21:32:40

标签: python python-3.x generator contextmanager

假设我有一个上下文管理器:

@contextmanager
def cm(x):
    y = f(x)
    z = yield y
    g(z)

如何将z发送到上下文管理器?

我试过了:

my_cm = cm()
with my_cm:
    my_cm.gen.send(123)

但是我得到了StopIteration,这可能是因为send会产生?

1 个答案:

答案 0 :(得分:2)

@contextmanager返回一个帮助函数,该函数又返回一个GeneratorContextManager实例,使用您的生成器作为管理上下文的方法。

它不能用作您可以发送的任何内容,next()会调用__enter__。您可以尝试使用.gen属性访问基础生成器:

my_cm.gen.send(123)

但是您必须包含额外 yield语句以防止该方法过早退出。请注意,__exit__将再次调用next()来结束生成器。

@contextmanager
def cm(x):
    y = f(x)
    a = yield y   # Run for `__enter__`, returning `y`; `.send()` resumes here
    yield         # Here we pause again
    g(a)

有效,因为它有第二个yield来再次暂停生成器,直到上下文管理器准备好最后一次调用next()