我正在根据http://www.dabeaz.com/coroutines/Coroutines.pdf
尝试coroutines管道问题是,如何从sink
获取价值而不是仅打印它?
以此代码为例
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())
使用此代码我得到:
>>> pipe.send(10)
100
然后我想得到返回值而不是打印它,我试图从接收器中产生:
@coroutine
def sink():
try:
while True:
yield (yield)
except GeneratorExit:
pass
但似乎无效,pipe.send(10)
仍然会返回None
而不是生成器。
那么如何获得返回值?
答案 0 :(得分:1)
pipe.send
为什么要返回生成器?你打算用返回值做什么?
无论是什么,都应该在sink
中完成。
但是,您可以将功能更改为
@coroutine
def produce(target):
while True:
n = (yield)
yield target.send(n*10)
@coroutine
def sink():
try:
while True:
yield (yield)
except GeneratorExit:
pass
产生target
产生的值,因此pipe.send(10)
只返回100
而不是打印它。
但现在你把生产者和消费者混在一起,这可能会给你带来一些麻烦。
回应你的评论:
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)]