如何从Python协程中获取返回值

15

我正在按照http://www.dabeaz.com/coroutines/Coroutines.pdf中的协程管道尝试编写代码。

问题是,如何从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

然后我希望获得返回值而不是将其打印出来,我尝试使用yield from sink:

@coroutine
def sink():
    try:
        while True:
            yield (yield)
    except GeneratorExit:
        pass

但是似乎没有起作用,pipe.send(10)仍然返回None而不是生成器。

那么我该如何获取返回值呢?

1个回答

3

为什么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)]

假设我输入了值A和值B,经过过滤、广播、处理等操作后,A生成了10个下沉值,而B生成了8个下沉值。我想要从A和B中获取最大值,但是如何判断哪个值是由A生成的,哪个值是由B生成的呢?有没有关于如何在下沉中实现这一点的想法? - lxyu
@lxyu 您可以发送密钥以了解哪个生产者生成了值,而sink可以具有状态以了解发送了哪些值以及哪个值是最大值。请查看我的编辑。 - sloth
我建议发送一个封装了所有需要的数据的对象! - Cucu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接