
There was just a bpo on this — discussion of exactly what an Iterable th or is. I’m pretty sure the conclusion was that in order to be an Iterator, an object needs to have __iter_. I’m not totally sure that it has to return self, but that is the expected behavior, so that it can be re-entrant. Of course, Python being Python, if in a given use case, you don’t need __iter__, you don’t have to have it. Just like the fact that you can pass anything with an appropriate read() method into json.load() will work, but that doesn’t make it a File. -CHB On Sun, Nov 28, 2021 at 9:42 PM David Mertz, Ph.D. <david.mertz@gmail.com> wrote:
On Mon, Nov 29, 2021, 12:33 AM Paul Bryan <pbryan@anode.ca> wrote:
1. Noted: Python's for statement will happily iterate over an object that only implements __next__. 2. The documentation is pretty clear on what is expected of an iterator: implement __next__ *and* __iter__. 3. It is perfectly reasonable for __iter__ to return something other than self; the documentation already reflects this. 4. If you believe the documentation is in error or the requirement should be relaxed, then further discussion is probably warranted.
Not so much "in error" as "could be clarified." Another couple words like "usually desirable" ... for an iterator to implement .__iter__() would cover it. Maybe I'll make a PR on the docs.
I agree that an iterator that doesn't implement .__iter__() is usually unnecessarily a PITA. Especially since "return self" is *usually* a perfectly good implementation.
On Mon, 2021-11-29 at 00:22 -0500, David Mertz, Ph.D. wrote:
On Mon, Nov 29, 2021, 12:16 AM Paul Bryan <pbryan@anode.ca> wrote:
And the second link?
Same comments, basically. But the more germane thing is that even assuming a class has both .__next__() and .__iter__(), it is perfectly reasonable for the latter to return something other than `self`.
The Foo and Bar classes are slightly contrived, but I've written production code where e.g. `iter(thing)` returns a new `thing.__class__` instance rather than self.
On Mon, 2021-11-29 at 00:11 -0500, David Mertz, Ph.D. wrote: If you
On Sun, Nov 28, 2021, 11:43 PM Paul Bryan <pbryan@anode.ca> wrote:
According to https://docs.python.org/3/glossary.html#term-iterator and https://docs.python.org/3/library/stdtypes.html#typeiter, iterators must implement the __iter__ method.
From your first link:
CPython implementation detail: CPython does not consistently apply the requirement that an iterator define __iter__().
That said, I don't think the description at the link is very good. Anyway, it's different from what I teach, and also different from how Python actually behaves. E.g.:
class Foo: ... def __iter__(self): ... return Bar() ... class Bar: ... def __next__(self): ... if random() > 0.5: ... raise StopIteration ... return "Bar" ... for x in Foo(): ... print(x) ... Bar Bar Bar
Or anyway, what would you call `bar := Bar()` if not "an iterator?!
On Sun, 2021-11-28 at 22:02 -0500, David Mertz, Ph.D. wrote:
On Sun, Nov 28, 2021, 8:59 PM Steven D'Aprano
To be an iterator, your object needs:
1. a `__next__` method which returns the next value; 2. and an `__iter__` method which returns self.
That's not quite right.
An iterator only needs .__next__(), and an iterable only needs .__iter__(). Returning self is a convenient, and probably the most common, way of creating an object that is both. But exceptions exist, and remain iterators and/or iterables.
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/WZNQ3B... Code of Conduct: http://python.org/psf/codeofconduct/
-- Christopher Barker, PhD (Chris) Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython