On Tue, Sep 14, 2021 at 9:31 PM Steven D'Aprano <steve@pearwood.info> wrote:
If it helps, I have tons of code that tests for iterators using:
iter(obj) is obj
That has been a documented requirement for the iterator protocol forever. Its in the PEP.
"A class that wants to be an iterator should implement two methods: a next() method that behaves as described above, and an __iter__() method that returns self."
However, the description clarifies that the reason for requiring __iter__ is weaker than the reason for requiring __next__.
We have objects such that:
iter(obj)
returns an iterator, but aren't themselves iterators.
Yeah, those are Iterables.
The most common example of that would be, I think, classes that define __iter__ as a generator method:
class A: def __iter__(self): for x in range(10): yield x
Then we have actual iterators, like iter(A()). They define `__iter__` that returns self.
I don't know what I would call an object that only has __next__, apart from "broken" :-(
It's still an iterator, since it duck-types in most cases where an iterator is required (notably "for", which is the primary use case for the iteration protocols -- it's in the first sentence of PEP 234's abstract). -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>