就我在Python中理解coroutine概念而言,基本上可以有两种不同的数据传递模式(抱歉,我找不到更好的术语):
这两种方法都有各自的优点。使用基于发送方的协同服务,我可以向许多消费者广播。
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现在我的问题是:是否有任何理智和简单的方式来统一这两种方法?例如,广播加法器的结果?
发布于 2013-11-25 11:44:15
我的猜测是,只有这样做才有可能:
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 iDecorator方法:
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 solutionhttps://stackoverflow.com/questions/20189924
复制相似问题