[Python-Dev] Re: Single- vs. Multi-pass iterability

Ka-Ping Yee ping@zesty.ca
Thu, 18 Jul 2002 12:59:01 -0700 (PDT)


I wrote:
> __iter__ is a red herring.
[...blah blah blah...]
> Iterators are currently asked to support both protocols.  The
> semantics of iteration come only from protocol 2; protocol 1 is
> an effort to make iterators look sorta like sequences.  But the
> analogy is very weak -- these are "sequences" that destroy
> themselves while you look at them -- not like any typical
> sequence i've ever seen!
>
> The short of it is that whenever any Python programmer says
> "for x in y", he or she had better be darned sure of whether
> this is going to destroy y.  Whatever we can do to make this
> clear would be a good idea.

On Wed, 17 Jul 2002, Guido van Rossum wrote:
> This is a very good summary of the two iterator protocols.  Ping,
> would you mind adding this to PEP 234?

I have now done so.

I didn't add the whole thing verbatim, because the tone doesn't fit:
it was written with the intent of motivating a change to the
protocol, rather than describing what the protocol is.  Presumably
we don't want the PEP to say "__iter__ is a red herring".

There's a bunch of issues flying around here, which i'll try to
explain better in a separate posting.  But i wanted to take care
of Guido's request first.  I have toned down and abridged my text
somewhat, and strengthened the requirement for __iter__().  Here
is what the "API specification" section now says:

    Classes can define how they are iterated over by defining an
    __iter__() method; this should take no additional arguments and
    return a valid iterator object.  A class that wants to be an
    iterator should implement two methods: a next() method that behaves
    as described above, and an __iter__() method that returns self.

    The two methods correspond to two distinct protocols:

    1. An object can be iterated over with "for" if it implements
       __iter__() or __getitem__().

    2. An object can function as an iterator if it implements next().

    Container-like objects usually support protocol 1.  Iterators are
    currently required to support both protocols.  The semantics of
    iteration come only from protocol 2; protocol 1 is present to make
    iterators behave like sequences.  But the analogy is weak -- unlike
    ordinary sequences, iterators are "sequences" that are destroyed
    by the act of looking at their elements.

    Consequently, whenever any Python programmer says "for x in y",
    he or she must be sure of whether this is going to destroy y.


-- ?!ng