想象一下,我有一些要运行的代码:
with F() as o:
while True:
a = o.send(2)
print(a)
这意味着F
类应该返回一个generator
并且它也是context manager
,通常我也希望上下文管理器也可以生成。
我尝试过:
class F:
def __enter__(self):
return self
def __exit__(self, *exc):
print('exit')
def __next__(self):
return 5
def __iter__(self):
return self
如预期的那样,它将返回AttributeError: 'F' object has no attribute 'send'
,我通过添加以下内容来处理此错误:
def send(self, param):
self.__next__()
但是我认为这不是一个好方法,我环顾四周并找到this,但是他们没有按我的意愿使用send
,我需要该实例作为生成器。
答案 0 :(得分:1)
您可以使用collections.abc
并从F
(manual pages)继承类Generator
的类。如果您实现 enter 和 exit ,则您的实例将是生成器,并且还具有上下文管理器支持:
from collections.abc import Generator
class F(Generator):
def __init__(self):
self.__my_generator = self._my_generator()
next(self.__my_generator) # prime the generator
def _my_generator(self):
while True:
v = yield 42
print('generator received ', v)
# context manager interace:
def __enter__(self):
return self
def __exit__(self, *exc):
print('exit')
# Generator interface:
def send(self, value):
return self.__my_generator.send(value)
def throw(self, typ, value=None, traceback=None):
return self.__my_generator.throw(typ, value, traceback)
with F() as o:
while True:
a = o.send(2)
print('I received ', a)
打印:
generator received 2
I received 42
...etc.