[Python-ideas] x=(yield from) confusion [was:Yet another alternative name for yield-from]

Jim Jewett jimjjewett at gmail.com
Fri Apr 3 03:43:08 CEST 2009


Summary:

I can understand a generator that returns something useful with each yield.

I can understand a generator that is used only for cooperative
multi-tasking, and returns nothing useful until the end.

yield from *as an expression* only really makes sense if the generator
is sending useful information *both* ways.  I can understand that sort
of generator only while reading the PEP; the code smell is strong
enough that I forget it by the next day.

Details:

On 4/2/09, Nick Coghlan <ncoghlan at gmail.com> wrote:
> Jim Jewett wrote:

>> If the "gencall" exhausts the generator f ...
>> If the "return value" of the generator really is important ...

> The intermediate values aren't necessarily discarded by "yield from"
> though: they're passed out to whoever is consuming the values yielded by
> the outermost generator.

I think this may be where I start to have trouble.  When I see the
statement form:

    def outer_g():
        yield from inner_g()

I expect inner_g to suspend execution, and it isn't that hard to
remember that it might do so several times.  I also expect the results
of inner_g.next() to be passed on out to outer_g's own caller, thereby
suspending outer_g.  So far, so good.

But when yield from is used as an expression, and I see:

    x = yield from g()

I somehow expect only a single call to g.next(), whose value gets
assigned to x, and not passed out.  I did read the PEP, in several
versions, and understood it at the time ... and still managed (several
times) to forget and misinterpret by a day or two later.

And yes, I realize it doesn't make too much sense to call g.next()
only once -- so I kept looking for a loop around that yield from
statement.  When there wasn't one, I shrugged it off like a with
clause -- and still didn't remember the actual PEP-intended meaning.

The times I did remember that (even) the expression form looped, I was
still boggled that it would return something other than None after it
was exhausted.  Greg's answer was that it was for threading, and the
final return was the real value.  This seems like a different category
of generator, but I could get my head around it -- so long as I forgot
that the yield itself was returning anything useful.

-jJ



More information about the Python-ideas mailing list