[Python-Dev] Single- vs. Multi-pass iterability
Oren Tirosh
oren-py-d@hishome.net
Tue, 9 Jul 2002 07:21:36 -0400
On Tue, Jul 09, 2002 at 04:43:25AM -0400, David Abrahams wrote:
> Yep. [Part of the reason I want to know whether I've got a one-shot
> sequence is that inspecting that sequence then becomes an
> information-destroying operation -- only being able to touch it once
> changes how you have to handle it]
>
> I was thinking one potentially nice way to introspect about
> multi-pass-ability might be to get an iterator and to see whether it was
> copyable. Currently even most multi-pass iterators can't be copied with
> copy.copy().
I wouldn't call it a one-shot sequence - it's just an iterator. The name
iterator is enough to suggest that it is disposable and good for just one
pass through the container.
If the object has an __iter__ method but no next it's not an iterator and
therefore most likely re-iterable. One notable exception is a file object.
File iterators affect the current position of the file. If you think about
it you'll see that file objects aren't really containers - they are already
iterators. The real container is the file on the disk and the file object
represents a pointer to a position in this container used for scanning it
which a pretty good definition of an iterator. The difference is cosmetic:
the next method is called readline and it returns an empty string instead of
raising StopIteration.
class ifile(file):
def __iter__(self):
return self
def next(self):
s = self.readline()
if s:
return s
raise StopIteration
class xfile:
def __init__(self, filename):
self.filename = filename
def __iter__(self):
return ifile(self.filename)
This pair of objects has a proper container/iterator relationship. The
xfile (stands for eXternal file, nothing to do with Mulder and Scully)
represents the file on the disk and each call to iter(xfileobject) returns
a new and independent iterator of the same container.
Oren