python的contextlib提供 Package 器,将生成器转换为上下文管理器:
from contextlib import contextmanager
@contextmanager
def gen():
yield
with gen() as cm:
...
生成器提供将值发送到刚刚生成的生成器的能力:
def gen():
x = yield
print(x)
g = gen()
next(g)
g.send(1234) # prints 1234 and raises a StopIteration because we have only 1 yield
有没有办法让这两种行为同时发生?我想向我的上下文管理器发送一个值,以便在处理时可以使用它 __exit__
. 比如说:
from contextlib import contextmanager
@contextmanager
def gen():
x = yield
# do something with x
with gen() as cm:
# generator already yielded from __enter__, so we can send
something.send(1234)
我不确定这是否是一个好/合理的想法。我觉得它确实打破了一些抽象层,因为我假设上下文管理器是作为 Package 生成器实现的。
如果这是一个可行的想法,我不确定是什么 something
应该是。
2条答案
按热度按时间yruzcnhs1#
生成一个函数的生成器
@contextmanager
可通过its直接访问gen
属性由于生成器无法访问上下文管理器,因此后者必须存储在上下文之前:重要的是,发电机必须具有正确的容量
yield
要点-@contextmanager
确保生成器在退出上下文后耗尽。@contextmanager
意志.throw
在上下文中引发异常,以及.send
None
完成后,基础生成器可以侦听的:不过,在许多情况下,将上下文管理器作为自定义类实现可能更容易。这避免了使用同一通道发送/接收值和暂停/恢复上下文带来的复杂性。
soat7uwm2#
我认为这是不可能的,也许有更好的方法来实现你想要的。
在pep 344中描述了contextmanager的实现方式
with
陈述contextmanager调用next
方法对用户的生成器函数执行两次,在__enter__
方法,并在__exit__
方法,而不发送任何值。您可能实现所需的方式大致如下(未经测试):