首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何统一发送方和接收方的协同?

如何统一发送方和接收方的协同?
EN

Stack Overflow用户
提问于 2013-11-25 10:35:27
回答 1查看 151关注 0票数 1

就我在Python中理解coroutine概念而言,基本上可以有两种不同的数据传递模式(抱歉,我找不到更好的术语):

  1. 基于发送者的:每个协同线使用来自“外部”的数据并将其发送给消费者。 def coro(消费者):而True: item =产率consumer.send(过程(项目)) 要建造管道,人们可以从外部管道到内部生产: 生产者(过滤器(接收器()
  2. 基于接收器的:每个协同线消耗其参数中的数据,并将其输出给消费者。 def coro(生产者):而True: item =next(生产者)产量过程(项目) 要建造管道,我们需要从内部到外部的协同线,这最终看上去更像是人们对功能的期望: 接收器(过滤器(生产者()

这两种方法都有各自的优点。使用基于发送方的协同服务,我可以向许多消费者广播。

代码语言:javascript
复制
    def broadcast(consumers):
        while True:
            item = yield
            for consumer in consumers:
                consumer.send(item)

然而,基于发送方的协同总是被限制在一个“输入”协同线上,因为它们无法区分是谁发送了什么(嗯,实际上是的,但这会很糟糕)。另一方面,对于基于接收器的协同线来说,这是微不足道的:

代码语言:javascript
复制
    def adder(producer1, producer2):
        while True:
            x = next(producer1)
            y = next(producer2)
            yield x + y

现在我的问题是:是否有任何理智和简单的方式来统一这两种方法?例如,广播加法器的结果?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-11-25 11:44:15

我的猜测是,只有这样做才有可能:

代码语言:javascript
复制
def adder(producer1, producer2, consumers):
    while True:
        x = next(producer1)
        y = next(producer2)
        for consumer in consumers:
            consumer.send(x+y)

然后打电话给adder(x_producer, y_producer, consumers)。从图表中可以看出:

加法器不能放在流水线的中间,原因是它必须具有对使用者和生产者的所有引用,如果我们在最高级别调用加法器,这是可能的。

更新:这里是另一种方法,它使加法器成为生成器:

代码语言:javascript
复制
class AdderWithBroadcast(object):

    consumers = []

    def __init__(self, x_prod, y_prod):
        self.x_prod = x_prod
        self.y_prod = y_prod

    def __iter__(self):
        return self

    def next(self):
        x = next(self.x_prod)
        y = next(self.y_prod)

        for consumer in self.consumers:
            consumer.send(x+y)

        return x+y

    def consumer():
        while True:
            a = (yield)
            print a, ' in consumer'


k = iter(range(10))
adder = AdderWithBroadcast(k, k)
cons = consumer()
cons.send(None)
adder.consumers.append(cons)
for i in adder: 
    #  I won't include the actual result here, you can try in no your own
    print i

Decorator方法

代码语言:javascript
复制
class Broadcaster(object):

    consumers = []

    def __init__(self, gen):
        self.gen = gen

    def __iter__(self):
        return self

    def __call__(self, *args, **kwargs):
        self.gen = self.gen(*args, **kwargs)

    def next(self):
        yielded = next(self.gen)

        for consumer in self.consumers:
            consumer.send(yielded)

        return yielded


@Broadcaster
def adder(producer1, producer2):
        while True:
            x = next(producer1)
            y = next(producer2)
            yield x + y
#  result is the same as in previous solution
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20189924

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档