如何统一发件人

就我理解Python中的协程概念而言,基本上可以有两种不同的数据传递模式(对不起,我找不到或者找不到更好的条件):

  • 基于发件人:每个协程从“外部”消费数据并将其发送给消费者,例如

    def coro(consumer):
        while True:
            item = yield
            consumer.send(process(item))
    

    为了建立管道,人们可以从外部协程向内部生成:

    producer(filter(sink()))
    
  • 基于接收者:每个协同程序从其参数中消费数据并将其交给消费者,例如

    def coro(producer):
        while True:
            item = next(producer)
            yield process(item)
    

    为了建立管道,可以从内部生成到外部协程,最终看起来更多的是人们对功能的期望:

    sink(filter(producer()))
    
  • 这两种方法都有各自的优点。 借助基于发件人的协程,我可以向许多消费者广播

        def broadcast(consumers):
            while True:
                item = yield
                for consumer in consumers:
                    consumer.send(item)
    

    然而,基于发件人的协程总是局限于一个“输入”协程,因为他们无法区分谁给他们发送了什么(好的,实际上是的,但那会是讨厌的)。 另一方面,基于接收器的协同程序是微不足道的:

        def adder(producer1, producer2):
            while True:
                x = next(producer1)
                y = next(producer2)
                yield x + y
    

    现在我的问题是:是否有统一两种方法的理智和简单的方法? 例如播放加法器的结果?


    我的猜测是只能做到这样的事情:

    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) 。 从图中可以看出: 在这里输入图像描述

    加法器不能放在流水线中间,原因是它必须全部引用消费者和生产者,如果我们在最高级调用加法器,这是可能的。

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

    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
    

    装饰者方法

    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
    
    链接地址: http://www.djcxy.com/p/53237.html

    上一篇: How to unify sender

    下一篇: using concatenated strings as function call in python