Python无限递归与生成器

时间:2014-10-12 14:48:18

标签: python recursion iterator

我正试图绕过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

2 个答案:

答案 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这样的简单函数,并且您不会获得超出递归深度的错误