In Python 3, it is standard procedure to make a class an iterable and iterator at the same time by defining both the __iter__
and __next__
methods. But I have problems to wrap my head around this. Take this example which creates an iterator that produces only even numbers:
class EvenNumbers:
def __init__(self, max_):
self.max_ = max_
def __iter__(self):
self.n = 0
return self
def __next__(self):
if self.n <= self.max_: # edit: self.max --> self.max_
result = 2 * self.n
self.n += 1
return result
raise StopIteration
instance = EvenNumbers(4)
for entry in instance:
print(entry)
To my knowledge (correct me if I'm wrong), when I create the loop, an iterator is created by calling something like itr = iter(instance)
which internally calls the __iter__
method. This is expected to return an iterator object (which the instance is due to defining __next__
and therefore I can just return self). To get an element from it, next(itr)
is called until the exception is raised.
My question here is now: if and how can __iter__
and __next__
be separated, so that the content of the latter function is defined somewhere else? And when could this be useful? I know that I have to change __iter__
so that it returns an iterator.
Btw the idea to do this comes from this site (LINK), which does not state how to implement this.