2010-12-13 3 views
6

Écrire une classe, comment implémenterpython - supporte .send() pour une classe?

foo.send (item)?

__iter__ permet d'itérer sur la classe comme un générateur, et si je veux que ce soit une coroutine?

+0

Ce n'est pas construit en Python comme '__iter__'. –

+0

Les générateurs et les coroutines sont le même type d'objet en Python. – katrielalex

Répondre

6

Voici un 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! 

Nous pouvons faire une classe qui contient un tel coroutine, et les délégués appelle à sa méthode send à la coroutine:

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?') 

Notez que foo agit comme un coroutine (dans la mesure où il a une méthode send), mais est une classe - il peut avoir des attributs et des méthodes qui peuvent interagir avec la coroutine.

Pour plus d'informations (et merveilleux exemples), voir Curious Course on Coroutines and Concurrency. David Beazley

+0

J'avais lu le «cours curieux» de beazley, et j'essayais d'implémenter une partie de ce que j'ai appris là-bas quand j'ai posé cette question. Merci d'avoir montré le def send(), je n'étais pas sûr si c'était l'approche à prendre ou pas .. –