Iterator / Iteratable confusion
Terry Reedy
tjreedy at udel.edu
Mon Feb 14 23:19:28 EST 2005
"Michael Spencer" <mahs at telcopartners.com> wrote in message
news:cuooip$1pd$1 at sea.gmane.org...
> Terry Reedy wrote:
>> iter(iterator) is iterator is part of the iterater protocol
> But, notwithstanding the docs, it is not essential that
> iter(iterator) is iterator
If a program depends on that invariant, then it is essential for that
program. Leaving such programs aside, I interpret this and your example
together as saying three things:
1. "There is more than one possible definition of 'iterator'."
Yes. Python could have defined many things differently. But I think it
important to have a clear definition of iterator (and other things) so one
can reason about program behavior.
2. "It is not essential to not do something wasteful as long as it is
otherwise inconsequential."
Usually true, but I don't see this as clarifying the relationship between
iterables and iterators in Python. (I am assuming that your example is
only meant to illustrate possibilities rather than usefulness.)
3. "You can substitute a copy of an object that is never mutated for the
object itself."
True, as long as you do not look at the id. But in practice, change of
state is essential to the function of nearly all iterators. For mutated
objects, one has to add the proviso that the copy is current and the
substitution total, so that there are no references left to the original.
But again, this has nothing in particular to do with iteration.
> >>> class A(object):
> ... def __iter__(self):
> ... return AnIterator()
> ...
> >>> class AnIterator(object): # an iterator that copies itself
By the narrower definition of iterator that I used, this is not an
iterator. Also, the replacement is only a copy if the instance has not
been mutated. Is your broader definition limited to return of initialized
copies or would it allow other things also?
> ... def next(self):
> ... return "Something"
> ... def __iter__(self):
> ... return AnIterator()
The second def statement is equivalent (except for identity) to
__iter__ = A.__iter__
To illustrate the point about mutation with a simple toy example:
a = A()
a.doc = 'My iterator'
b = iter(a)
b is not a copy of a as it is, but only as it was initially.
Terry J. Reedy
More information about the Python-list
mailing list