2013-09-04 16 views
8

Próbuję współprogram rurociągu według http://www.dabeaz.com/coroutines/Coroutines.pdfJak uzyskać wartości zwracanej z współprogram w Pythonie

pytanie brzmi, w jaki sposób można uzyskać wartość z sink zamiast drukować tylko to?

Weź ten kod np

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()) 

Z tego kodu uzyskać:

>>> pipe.send(10) 
100 

Następnie chcę, aby uzyskać wartość zwrotną zamiast je drukować, staram się, uzyskując z umywalką:

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

Ale wydaje się nie działać, pipe.send(10) nadal zwraca None zamiast generator.

Jak uzyskać wartość zwrotu?

Odpowiedz

1

Dlaczego powinienem zwrócić pipe.send generator? I co zamierzasz zrobić ze zwróconą wartością?

Cokolwiek to jest, należy to zrobić w sink.

Można by jednak zmienić swoje funkcje do

@coroutine 
def produce(target): 
    while True: 
     n = (yield) 
     yield target.send(n*10) 

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

uzyskując wartość uzyskanych przez target, więc pipe.send(10) po prostu wrócić 100 zamiast drukować je.

Ale teraz mieszasz producenta i konsumenta, co potencjalnie może wywołać ból głowy.


W odpowiedzi na Twój komentarz:

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)] 
+0

powiedzieć, jeśli pcham w wartości A i wartość B, po filtrze, transmisji, przetwarzania etc, Wygenerowane 10 wartości tonąć, a B generowane 8 wartości tonąć. I chcę maksymalną wartość od A i maksymalną wartość od B, ale jak mam powiedzieć, która wartość jest generowana z A lub z B? Masz pomysł, jak to zrobić w zlewie? – lxyu

+0

@lxyu Możesz wysłać klucz, aby dowiedzieć się, który producent wytworzył wartość, a zlew może mieć stan, aby wiedzieć, które wartości są wysyłane i która wartość jest wartością maksymalną. Zobacz moją edycję. – sloth

+0

Proponuję wysłać obiekt, który zawiera wszystkie potrzebne dane! – Cucu

Powiązane problemy