[Python-ideas] Introduce collections.Reiterable

Steven D'Aprano steve at pearwood.info
Thu Sep 19 14:18:29 CEST 2013


On Thu, Sep 19, 2013 at 07:12:26PM +1000, Nick Coghlan wrote:

> is there any obvious case where "iterable but
> not an iterator" gives the wrong answer?

I'm not sure if it counts as "obvious", but one can write an iterator 
that is re-iterable. A trivial example:

class Reiter:
    def __init__(self):
        self.i = 0
    def __next__(self):
        i = self.i
        if i < 10:
            self.i += 1
            return i
        self.i = 0
        raise StopIteration
    def __iter__(self):
        return self


I know that according to the iterator protocol, such a re-iterator 
counts as "broken":

[quote]
The intention of the protocol is that once an iterator’s next() method 
raises StopIteration, it will continue to do so on subsequent calls. 
Implementations that do not obey this property are deemed broken. (This 
constraint was added in Python 2.3; in Python 2.2, various iterators are 
broken according to this rule.)

http://docs.python.org/2/library/stdtypes.html#iterator-types


but clearly there is a use-case for re-iterable "things", such as dict 
views, which can be re-iterated over. We just don't call them iterators. 
So maybe there should be a way to distinguish between "oops this 
iterator is broken" and "yes, this object can be iterated over 
repeatedly, it's all good".

At the moment, dict views aren't directly iterable (you can't call 
next() on them). But in principle they could have been designed as 
re-iterable iterators.

Another example might be iterators with a reset or restart method, or 
similar. E.g. file objects and seek(0). File objects are officially 
"broken" iterators, since you can seek back to the beginning of the 
file. I don't think that's a bad thing.

But nor am I sure that it requires a special Reiterable class so we can 
test for it.


-- 
Steven


More information about the Python-ideas mailing list