2010-12-13 30 views
6

Pisanie zajęć, jak zaimplementowaćpython - wsparcie .send() dla klasy?

foo.send (przedmiot)?

__iter__ pozwala na iterowanie po klasie jak generator, a co jeśli chcę, aby był to coroutine?

+0

To nie jest wbudowane w Pythonie jak '__iter__'. –

+0

Generatory i coroutines są tym samym typem obiektów w Pythonie. – katrielalex

Odpowiedz

6

Oto basic example of a coroutine:

def coroutine(func): 
    def start(*args,**kwargs): 
     cr = func(*args,**kwargs) 
     cr.next() 
     return cr 
    return start 

@coroutine 
def grep(pattern): 
    print "Looking for %s" % pattern 
    while True: 
     line = (yield) 
     if pattern in line: 
      print(line) 

g = grep("python") 
# Notice how you don't need a next() call here 
g.send("Yeah, but no, but yeah, but no") 
g.send("A series of tubes") 
g.send("python generators rock!") 
# Looking for python 
# python generators rock! 

Możemy zrobić klasę, która zawiera taką współprogram, a delegaci wzywa do jego send metody do współprogram:

class Foo(object): 
    def __init__(self,pattern): 
     self.count=1 
     self.pattern=pattern 
     self.grep=self._grep() 
    @coroutine 
    def _grep(self): 
     while True: 
      line = (yield) 
      if self.pattern in line: 
       print(self.count, line) 
       self.count+=1 
    def send(self,arg): 
     self.grep.send(arg) 

foo = Foo("python") 
foo.send("Yeah, but no, but yeah, but no") 
foo.send("A series of tubes") 
foo.send("python generators rock!") 
foo.pattern='spam' 
foo.send("Some cheese?") 
foo.send("More spam?") 

# (1, 'python generators rock!') 
# (2, 'More spam?') 

Zauważ, że foo działa jak coroutine (o ile ma metodę wysyłania), ale jest klasą - może mieć atrybuty i metody, które mogą wchodzić w interakcję z coroutine.

Aby uzyskać więcej informacji (i wspaniałych przykładów), patrz David Beazley na Curious Course on Coroutines and Concurrency.

+0

Przeczytałem "ciekawy kurs" Beazleya i próbowałem wdrożyć niektóre z tego, czego się tam nauczyłem, gdy zadałem to pytanie. Dzięki za pokazanie def send(), nie byłem pewien, czy to było podejście do podjęcia, czy nie .. –