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.
On Mon, 2021-11-29 at 00:22 -0500, David Mertz, Ph.D. wrote: > On Mon, Nov 29, 2021, 12:16 AM Paul Bryan <pbr...@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 <pbr...@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-le...@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/E3WYSX52KOFDHP3NNSZRBKDLIENGMUY3/ Code of Conduct: http://python.org/psf/codeofconduct/