http://www.dabeaz.com/coroutines/Coroutines.pdf
http://www.dabeaz.com/coroutines/Coroutines.pdf
The question is, how can I get value from the sink rather than only print it?
Take this code for example
def coroutine(func):
def start(*args, **kwargs):
cr = func(*args, **kwargs)
next(cr)
return cr
return start
@coroutine
def produce(target):
while True:
n = (yield)
target.send(n*10)
@coroutine
def sink():
try:
while True:
n = (yield)
print(n)
except GeneratorExit:
pass
sk = sink()
pipe = produce(sink())
With this code I get:
>>> pipe.send(10)
100
Then I want to get the return value rather than print it, I try to yield from sink:
@coroutine
def sink():
try:
while True:
yield (yield)
except GeneratorExit:
pass
But it seems not working, pipe.send(10) still returns None rather than a generator.
So how shall I get the return value?
Why should pipe.send return a generator? And what are you going to do with the returned value?
Whatever it is, it should be done in sink.
You could, however, change your functions to
@coroutine
def produce(target):
while True:
n = (yield)
yield target.send(n*10)
@coroutine
def sink():
try:
while True:
yield (yield)
except GeneratorExit:
pass
to yield the value yielded by target, so pipe.send(10) will just return 100 instead of printing it.
But now you mix the producer and the consumer, which will potentially give you some headache.
In response to your comment:
from collections import defaultdict
def coroutine(func):
def start(*args, **kwargs):
cr = func(*args, **kwargs)
next(cr)
return cr
return start
@coroutine
def produce(key, target):
while True:
n = (yield)
target.send((key, n*10))
class Sink(object):
def __init__(self):
self.d = defaultdict(lambda: None)
self.co = self.sink()
def send(self, *args):
self.co.send(*args)
@coroutine
def sink(self):
try:
while True:
key, n = yield
self.d[key] = max(self.d[key], n)
except GeneratorExit:
pass
sk = Sink()
pipeA = produce("A", sk)
pipeB = produce("B", sk)
pipeA.send(10)
pipeA.send(20)
pipeA.send(40)
pipeB.send(20)
pipeB.send(40)
pipeB.send(60)
print sk.d.items() # [( A , 400), ( B , 600)]
http://stackoverflow.com/questions/18611142/how-to-get-return-value-from-coroutine-in-python