[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Iterators, iterables and special objects

On Thu, Jul 23, 2020 at 5:55 PM Peter Sl??ik <peter.slizik at> wrote:
> > Python's design that iter(iterator) is iterator is extremely handy.
> >
> Yes,  but it has the unfortunate consequence that an iterator is expected
> to define
> def __iter__(self):    return self
> which I saw people *not* doing, supposedly because the official
> documentation says that it needs to be done, but does not explain why (and
> the interpreter does not enforce it, and the code works anyway).

Works in what way? You can't use it in a 'for' loop if it doesn't
define __iter__.

> Moreover, some tutorial authors make it even more difficult with using the
> terms iterator and iterable interchangeably. A notorious example is this
> wiki:
> It says:
> *Here is an *iterator* that returns a random number of 1's: *
> class RandomIterable:    def __iter__(self):        return self

Yes? It is indeed an iterator, since its iter method returns itself.
It is also iterable, since it has an iter method. The article goes on
to explain this. I don't think they're being used interchangeably

> I remember the time when I started to look into iterators, and frankly,
> with this wiki article, it took me ages to understand,why do iterables
> return self in their *__iter__* method.

It's so you can do things like this:

def show_with_header(stuff):
    stuff = iter(stuff)
    hdr = next(stuff)
    for line in stuff:
        if new_page(): print(hdr)

You can pass this any (non-empty) iterable and it'll work. If __iter__
didn't return self, both this function and the for loop inside it
would need to check for an iterator and an iterable, and there'd be
the possibility of a conflict.

Having __iter__ return self is a pretty elegant way to handle it. I
suppose the same thing could be signalled some other way (having it
return None, for instance), but it wouldn't gain you anything.