我正试图绕过python生成器,因此,我正在尝试使用yield打印无限嵌套对象,但我发现我仍然遇到了吹出堆栈的问题。理想情况下,我希望能够产生并打印每件物品,但我无法弄清楚我做错了什么:
class Parent:
def __init__(self, name, child=None):
self._name = name
self._child = child
def get_name(self):
return self._name
def get_child(self):
return self._child
def set_child(self, child):
self._child = child
def __iter__(self):
next_child = self._child.get_child()
if not next_child:
raise StopIteration
else:
self._child = next_child
yield next_child
def __str__(self):
return "%s has %s" % (self._name, self._child)
if __name__ == '__main__':
p1 = Parent("child")
p2 = Parent("child", p1)
p1.set_child(p2)
for t in p1:
print t
答案 0 :(得分:1)
jonrsharpe指出,代码中的错误是由__str__
函数引起的,该函数试图返回:
child has child has child has child has child has ...
你可能意味着:
def __str__(self):
return "%s has %s" % (self._name, self._child.get_name())
# return 'child has child'
此外,__iter__
应该是生成器函数。生成器函数需要包含一个循环才能不断生成值。所以它应该是这样的:
def __iter__(self):
next_child = self._child.get_child()
while next_child:
yield next_child
next_child = next_child.get_child()
# When the function ends, it will automatically raise StopIteration
通过修改,您的代码会打印出无尽的child has child
行。
有关生成器函数的更多信息,另请参阅What does the yield keyword do in Python?。
答案 1 :(得分:0)
无限递归发生在__str__
函数。它与__iter__
函数无关。
当您执行print t
时,它会执行t._child.__str__
,然后执行t._child._child.__str__
,依此类推。
尝试将__str__
函数定义更改为像return self._name
这样的简单函数,并且您不会获得超出递归深度的错误