2010-09-14 48 views
6

No soy un tipo pitón y estoy tratando de entender algún código python. Me pregunto qué hace la última línea del código siguiente. ¿Se devuelve ese tipo de objetos múltiples? o la lista de 3 objetos devueltos?¿Qué significa esta sintaxis de python?

req = SomeRequestBean() 
req.setXXX(xxx) 
req.YYY = int(yyy) 

device,resp,fault = yield req   #<----- What does this mean ? 

Respuesta

9

Hay dos cosas pasando en esa línea. El uno más fácil de explicar es que la declaración yield devuelve un valor que es una secuencia, por lo que las comas tomar valores de la secuencia y los puso en las variables, muy parecido a éste:

>>> def func(): 
...  return (1,2,3) 
... 
>>> a,b,c = func() 
>>> a 
1 
>>> b 
2 
>>> c 
3 

Ahora, la declaración yield se usa para create a generator, que puede devolver una cantidad de valores en lugar de solo uno, devolviendo un valor cada vez que se usa yield. Por ejemplo:

>>> def func(): 
...  for a in ['one','two','three']: 
...   yield a 
... 
>>> g = func() 
>>> g.next() 
'one' 
>>> g.next() 
'two' 
>>> g.next() 
'three' 

En efecto, la función se detiene en la declaración yield, esperando que se le solicite el siguiente valor antes de continuar. En el ejemplo anterior, next() obtiene el siguiente valor del generador. Sin embargo, si utilizamos send() lugar podemos enviar valores de vuelta al generador que son devueltos por la instrucción yield de nuevo a la función:

>>> def func(): 
...  total = 0 
...  while True: 
...  add = yield total 
...  total = total + add 
... 
>>> g = func() 
>>> g.next() 
0 
>>> g.send(10) 
10 
>>> g.send(15) 
25 

Poniendo todo esto junto obtenemos:

>>> def func(): 
...  total = 0 
...  while True: 
...   x,y = yield total 
...   total = total + (x * y) 
... 
>>> g = func() 
>>> g.next() 
0 
>>> g.send([6,7]) 
42 

Un generador utilizado de esta manera es called a coroutine.

4

la última línea es descomprimir un tupla a partir del método de la co-rutina que el código que se muestra se encuentra en send

es decir que se produce en una función:.

def coroutine(*args): 
    yield None 
    req = SomeRequestBean() 
    req.setXXX(xxx) 
    req.YYY = int(yyy) 

    device,resp,fault = yield req 

existe un código de cliente que en algún lugar se parece a esto.

co = coroutine(*args) 
next(co) # consume the first value so we can start sending. 
co.send((device, resp, fault)) 

un ejemplo más simple de este que no implique corrutinas es algo a lo largo de las líneas de

a, b, c = (1, 2, 3) 

o (un poco más de lujo)

for a, b in zip(['a', 'b'], [1, 2]): 
    print a, b 

aquí zip devuelve tuplas que se interponen descomprimido a a y b. entonces una tupla se vería como ('a', 1) y luego a == 'a' y b == 1.