2010-01-07 5 views
29

Estoy familiarizado con el rendimiento para devolver un valor gracias sobre todo a this question¿Qué significa ceder como tarea? miVar = (rendimiento)

pero lo hace el rendimiento cuando se está en el lado derecho de una asignación?

@coroutine 
def protocol(target=None): 
    while True: 
     c = (yield) 

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

me encontré con esto, en los ejemplos de código de this blog, mientras que la investigación máquinas de estado y co-rutinas.

Respuesta

35

La instrucción yield utilizada en una función convierte esa función en un "generador" (una función que crea un iterador). El iterador resultante normalmente se reanuda llamando al next(). Sin embargo, es posible enviar los valores de la función llamando al método send() en lugar de next() reanudarla:

cr.send(1) 

En el ejemplo que se asignaría el valor 1 a c cada vez.

cr.next() es efectivamente equivalente a cr.send(None)

+0

1 para una buena explicación –

+1

para notar, antes de poder llamar 'send()' en un generador, usted tiene que llamar 'next()' para comenzar la realidad o obtendrá un TypeError que dice: 'TypeError: no puede enviar un valor que no sea ninguno a un generador recién iniciado – Caumons

11

Puede enviar valores al generador utilizando la función send.

si se ejecuta:

p = protocol() 
p.next() # advance to the yield statement, otherwise I can't call send 
p.send(5) 

continuación yield volverá 5, por lo que el interior del generador c será 5.

Además, si se llama a p.next(), yield volverá None.

Puede encontrar más información here.