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/

Reply via email to