[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