iterator.next() confusion
Steven Taschuk
staschuk at telusplanet.net
Mon Jun 2 02:46:45 EDT 2003
Quoth Clark C. Evans:
> Hello all. The iterator PEP doesn't seem to say if the next() method
> of the iterator could be cached during a loop, for example:
[...]
> Code like the above seems to work with most iterables, however,
> it will get into an endless loop with the following iterator:
>
> class evilIterator:
[...iterator for which calling self.next rebinds self.next...]
This kind of iterator actually fails in for loops if it is made
new-style.
> Which is incorrect use of the iterator PEP? [...]
For new-style objects only type(it).next is used; whether it is
shadowed by an instance attribute doesn't matter. So my feeling
is that using an instance-specific .next is not kosher, even
though it works for old-style iterators. (Note that the PEP
speaks only of defining .next in the class.)
It is possible to write an evil new-style iterator, though:
class NewEvilIterator(object):
def __iter__(self):
return self
def next(self):
NewEvilIterator.next = NewEvilIterator.next_stop
return 1
def next_stop(self):
raise StopIteration()
This works, sort of. Certainly a for loop looks up the .next
class attribute anew at each iteration. Of course, as a real
technique this is useless; you can't have multiple independent
instances of such a class, even if their lifetimes don't overlap.
I can't think of a way to write a usable new-style iterator class
which breaks under caching of .next.
--
Steven Taschuk staschuk at telusplanet.net
Receive them ignorant; dispatch them confused. (Weschler's Teaching Motto)
More information about the Python-list
mailing list