如何统一发件人
就我理解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