[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