On Tue, Nov 25, 2014 at 9:59 AM, Guido van Rossum <guido@python.org> wrote:
On Tue, Nov 25, 2014 at 9:47 AM, Chris Barker <chris.barker@noaa.gov> wrote:

[...] I like how it support my goal of keeping the behavior of iterator classes and generators consistent.

This is a great summary of the general confusion I am trying to clear up. The behavior of all types of iterators (including generators) from the *caller's* perspective is not in question and is not changing. It is very simple: you call next(it) (or it.__next__(), and it returns either the next value or raises StopIteration (and any other exception is, indeed, an exception).

From the POV of *implementor*, iterator classes and generators have never been at all alike -- one uses *return* to produce a new value, the other uses *yield*. Returning without a value from a __next__() method is seen as producing a None value by the caller; returning from a generator is translated into a StopIteration which will be interpreted by the caller as the end of series.

Once you start nesting these things, the distinction between "implementor" and "caller" gets mingled. And I think this is all about how nested generators behave, yes?

If I am implementing a iterator of some sort (generator function or iterator class), and I call next() inside my code, then I am both a implementor and caller. And if I'm also writing helper functions, then I need to know about how StopIteration will be handled, and it will be handled a bit differently by generators and iterator classes.

But not a big deal, agreed, probably a much smaller deal that all the other stuff you'd better understand to write this kind of code anyway.



Christopher Barker, Ph.D.

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception