Generators versus Coroutines

Tim Peters tim.peters at gmail.com
Sat Aug 14 22:24:54 CEST 2004


[Timothy Fitz]
> It seems to me that in python, generators are not truly coroutines.

Yes, formally speaking Python generators are semi-coroutines.

> I do not understand why.

Please read the PEP:

    http://www.python.org/peps/pep-0255.html

> What I see is that generators are used almost exclusively for
> generation of lists just-in-time. Side effects are frowned upon.

Simple uses are naturally most common.

> Coroutines, in contrast, are like split functions where
> side effects are often as important or more important than return
> values. I am currently writing a real time strategy game where I have
> visual effects and use generators as coroutines which yield after
> processing a single frame of the effect. I can easily make an object
> rotate indefinitely with a scant four or five lines of code, all of
> which is in one place. So knowing that the difference between a
> generator and a coroutine is minor, I come (in a very roundabout way)
> to my issue. Why can I use "return" without an expression and it
> implicitly returns None

If you explicitly intend to return None as a value, it's terrible
practice to spell that as

    return

instead of as

    return None

It's equally terrible practice to rely on that "falling off the end"
of a Python function returns None, when you expliclty intend to return
a None value.

Plain "return" is intended to be used in Python only when
*conceptually* no value is being returned, as in "a subroutine" as
opposed to "a function".  The language doesn't enforce the latter
distinction, but it's intended all the same.

> but I can't do the same thing with "yield" ?

It's the purpose of "yield" to deliver a value.  There was no intent
that it be possible to yield without delivering a value.  If you want
to deliver the value None, then say

    yield None

If you want a concept of yielding without delivering a value, that's
simply not a use case Python's generators intended to address.  If you
wish, you can adhere to a *convention* that "yield None" (or "yield
False", or "yield 42", ...) means "I'm not really delivering a value".



More information about the Python-list mailing list