Does a python iterator really have to be an iterable?

Viewed 63

I have always found it horribly confusing that python iterators are required to be iterables, since it seems to me that attempting to iterate over an iterator is, logically, a type mismatch. Is there a reason for this requirement?

The explanation, according to the definition of iterator, is:

Iterators are required to have an __iter__() method that returns the iterator object itself so every iterator is also iterable and may be used in most places where other iterables are accepted.

But that doesn't explain it: why is advantageous for an iterator to be "used in most places that accept iterables"? As far as I can see, this only adds unnecessary confusion, since, as far as I am aware, I don't want my iterators to be used in places where iterables are accepted.

That is, you say this:

for item in myContainer:

never this, in my experience:

for item in myIterator:

So, when I define an iterator class, my inclination is to simply ignore that strange requirement; that is, I am inclined to define __next__() as usual, but refrain from defining __iter__(). Such "iterators" still seem to work perfectly fine, and are less confusing and less error prone (more typesafe) than they would be if I followed the requirement.

Will any harm come to me, my program, or my users if I do this? That is:

  • will my "iterators" fail to be useful in some way?
  • might they stop working as intended, in a future version of python?

Further, I wonder if there is a chance that this strange requirement might simply be removed in some future version of the python documentation, without harm.

I see that there is already a somewhat-mysterious note in the above-linked doc, shortly after the above-quoted section:

CPython implementation detail: CPython does not consistently apply the requirement that an iterator define __iter__().

That's interesting information, but I'm not sure what to conclude from it, in terms of guidance. It seems to me that one possible interpretation is "you may not need to make your iterators be iterables after all". And an opposing possible interpretation is "beware: if you make an iterator that isn't an iterable, it may appear to work in some or most cases, but then it may unexpectedly fail to work in some situations or future versions of CPython". A third possible interpretation is something like "we acknowledge that this is a strange requirement, and no one has a clear idea of what we're doing with it or whether/where it should be enforced".

0 Answers
Related