[Python-ideas] Introduce collections.Reiterable

Steven D'Aprano steve at pearwood.info
Mon Sep 23 01:46:37 CEST 2013

On Sun, Sep 22, 2013 at 12:37:52PM -0400, Terry Reedy wrote:
> On 9/22/2013 10:22 AM, Nick Coghlan wrote:
> >The __getitem__ fallback is a backwards
> >compatibility hack, not part of the formal definition of an iterable.
> When I suggested that, by suggesting that the fallback *perhaps* could 
> be called 'semi-deprecated, but kept for back compatibility' in the 
> glossary entry, Raymond screamed at me and accused me of trying to 
> change the language. He considers it an intended language feature that 
> one can write a sequence class and not bother with __iter__. I guess we 
> do not all agree ;-).

Raymond did not "scream", he wrote *one* word in uppercase for emphasis.
I quote:

    It is NOT deprecated.   People use and rely on this behavior.  It is 
    a guaranteed behavior.  Please don't use the glossary as a place to 
    introduce changes to the language.

I agree, and I disagree with Nick's characterization of the sequence 
protocol as a "backwards-compatibility hack". It is an elegant protocol 
for implementing iteration of sequences, an old and venerable one that 
predates iterators, and just as much of Python's defined iterable 
behaviour as the business with calling next with no argument until it 
raises StopIteration. If it were considered *merely* for backward 
compatibility with Python 1.5 code, there was plenty of opportunity to 
drop it when Python 3 came out.

The sequence protocol allows one to write a lazily generated, 
potentially infinite sequence that still allows random access to items. 
Here's a toy example:

py> class Squares:
...     def __getitem__(self, index):
...         return index**2
py> for sq in Squares():
...     if sq > 9: break
...     print(sq)

Because it's infinite, there's no value that __len__ can return, and no 
need for a __len__. Because it supports random access to items, writing 
this as an iterator with __next__ is inappropriate. Writing *both* is 
unnecessary, and complicates the class for no benefit. As written, 
Squares is naturally thread-safe -- two threads can iterate over the 
same Squares object without interfering.


More information about the Python-ideas mailing list