Reputation: 105
class Kids():
def __init__(self, list_of_kids):
self.kids = list_of_kids
def __next__(self):
return 'kawabanga'
def __iter__(self):
return self
kid = Kids([1,2,3])
kids_iter = iter(kid)
print(kid)
print(kids_iter)
print(iter([1,2,3]))
I've built the code above as an example. I receive the following output:
<__main__.Kids object at 0x102977b38>
<__main__.Kids object at 0x102977b38>
<list_iterator object at 0x102977be0>
As far as I understand: iter()
should return an iterator object, but as you can see when I enter the function iter()
the object Kids
it returns a Kids
object instead of an iterator object.
Can you please explain me why it doesn't return an iterator object when I call iter()
on the object Kids
?
Upvotes: 0
Views: 143
Reputation: 696
This happens because you are overwriting iter()
behaviour when setting __iter__
on the class. As you can see, you return self, so you basically redefined what iter(Kids)
does.
The correct way to implement this is to yield
, instead of return
in __iter__
. This of course only makes sense if you plan on combining it with something like a for loop, so that you iterate over multiple objects. Otherwise __iter__
and __next__
will only ever give you a single object instance.
Upvotes: 2
Reputation: 160437
Because you return self
from Kids.__iter__
and not a special iterator
object as list
objects do (list_iterator
).
Your class is itself the iterator since it defines __iter__
and __next__
.
If, instead, you want to handle the iteration at a separate object for the Kids
class (and there's plenty of reasons to want to do that), create a Kids_Iterator
object that defines __iter__
and __next__
and make Kids.__iter__
return a new instance of the Kids_Iterator
class.
Upvotes: 3