我正在尝试使用带有Python类的生成器,它的工作方式与链接列表类似.
这是一个非常简单的例子:
class GeneratorTest():
def __init__(self, list):
if list:
self.elem = list[0]
if list[1:]:
self.n = GeneratorTest(list[1:])
else:
self.n = None
def __iter__(self):
return self
def next(self):
my_next = self
while my_next is not None:
yield my_next
my_next = my_next.n
Run Code Online (Sandbox Code Playgroud)
当然这只是一个例子,但足以说明这一点.
现在,我希望能够调用类似的东西:
g = GeneratorTest([1,2,3,4,5])
for x in g:
print x
Run Code Online (Sandbox Code Playgroud)
当循环达到最后一个值时循环停止,但for循环只是无休止地继续.
我对发电机很新,所以我确定这是我在这里缺少的一个基本前提.
这个问题与我产生创建生成器的相同对象有关吗?我敢肯定,如果我有一个包含GeneratorTest对象列表的对象,我可以非常简单地返回这些对象中的每一个,但我觉得应该有一种方法可以使这个工作没有"包装"对象.
我在这里错过了什么?
问题是next(或者,在 Py3 中,__next__)不应该是生成器 - 它应该在外部维护其状态以及return每个值。你的每次都会返回一个新的生成器,但由于 Python 不会迭代该生成器,因此你的循环实际上从未运行。这可能意味着您想要__iter__返回除最初之外的其他内容self(尽管它返回的任何内容都需要有一个__iter__返回 self 的内容)。
但好消息是,生成器的存在正是为了帮助您跟踪这些规则。将当前next代码移入__iter__,一切正常 - Python会迭代任何__iter__返回值(如您所期望的)。