How do you make a new class work in a for loop?
What do I need to put in the
[...] to make that work?
This is the most obvious answer: implement
__next__(self) (or just
next(self) in Python 2), to fulfill the iterator
Running this works like we wanted:
This will also work anywhere an iterable is needed:
Note also that we are changing the object on every iteration, so we need a new object every time:
In some cases, that will be expected; in others, that will be a surprising annoyance.
This is the most straight-forward method, in the sense that it most obviously fulfills the needs of the iterator protocol, but it is also not the only method, or in most cases the simplest to write.
__iter__as a generator
We can also implement
__iter__ in such a way that it returns a generator, just by using the
yield keyword. If you’re not familiar with Python generators, go look them up! They’re often
useful! If you are, then you will not be surprised by the code below:
That’s much simpler code, more “Pythonic”, in my mind, and even has the added advantage that you can
reuse the same object;
self.N doesn’t change when you iterate. Of course, this may not be an
advantage, depending on what you’re using it for, but if you can do it that way, its pretty nice!
I just learned this from a Raymond Hettinger talk,
but apparently, if you implement
__getitem__, you get iteration for free:
This is longer than the ones above, but unlike them, you’re also getting indexing (
obj[i]) and a
len method (
len(obj)). If you’re wrapping a protocol from some other language like C or Java,
where you access things with some
getSize() method and a
get(float index) method, this is
clearly the way to go.
__next__with another class
This is the “long way”, which everything else here is in some way a shortcut to:
This works exactly the same as the ones above, and its reusable. Our first two methods are
“shortened” forms of this: the first method uses the same class for
second uses a generator to produce its
TestIter iterator, and the third… well, the third is more
magic than I understand. PEP 234 clearly states that
you can do this, but I don’t understand how it works internally.