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.