I'm trying to wrap my head around python generators and as a result, I'm trying to print infinitely nested objects using yield, but I find that I still get problems with blowing out the stack. Ideally, I'd like to be able to yield and print each item as it comes along but I can't figure out what I'm doing wrong:
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
The error in your code, as noted by jonrsharpe, is due to the __str__
function, which tries to return:
child has child has child has child has child has ...
You probably mean:
def __str__(self):
return "%s has %s" % (self._name, self._child.get_name())
# return 'child has child'
Also, __iter__
should be a generator function. Generator functions need to contain a loop in order to continually produce values. So it should be something like:
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
With the modifications, your code prints endless lines of child has child
.
See also What does the yield keyword do in Python? for more information about generator functions.
The infinite recursion is happening at __str__
function. It has nothing to do with the __iter__
function.
when you do print t
, it executes t._child.__str__
which in turn executes t._child._child.__str__
and so forth.
try changing the __str__
function definition to something simple like return self._name
and you won't get a recursion depth exceeded error
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.