Generators versus Coroutines

Michael Sparks zathras at thwackety.com
Sun Aug 15 11:22:58 EDT 2004


On Sun, 15 Aug 2004, Nick Patavalis wrote:
...
> For me it would be *tremendously* usefull if one could yield across
> multiple levels of function calls. If this was supported, then most
> uses of O/S treads could be replaced by generators.

You can do this already if you use Armin Rigo's Greenlets which, whilst
included in Stackless appear to work perfectly fine with standard python.
(I've only tested with 2.3 FWIW)

Trivial modification of one of the supplied examples:

import greenlet
def switchWrapper(): greenlet.main.switch()
def doSwitch(): switchWrapper()

def f(n):
    for i in range(n):
        print i
        doSwitch()

gf = [greenlet.greenlet(f, (10+5*j,)) for j in range(2)]

while 1:
    for g in gf:
        g.switch()

(Mainly ripped out exception handling for clarity)

One of the examples (test3.py) supplied shows how to build "standard"
generators using greenlets. The differences however are a) the function
has to be explicitly turned into a generator, b) you use a "Yield()"
function call to return the value c) it's not limited to yielding through
1 level. (ie what you just asked for :)

Example usage of the Greenlet-generators:

def foobar(i): Yield(i)
def g(n):
    for i in range(n):
        foobar(i)

g = generator(g)
for j in g(10):    print j

Indeed using the new decorator syntax you could probably simplify this to:

def foobar(i): Yield(i)

@generator
def g(n):
    for i in range(n):
        foobar(i)

for j in g(10):    print j

(Or pick your favourite decorator syntax ;-)

Regards,


Michael.




More information about the Python-list mailing list