2016-12-01 5 views
4

Je suis en train de la fonction d'envoi de générateur, je m'y attendais send changera la valeur qui est en cours de rendement, alors j'ai essayé en ipython:Python "send" méthode ne modifie pas la valeur de "next"?

In [17]: def z(n): 
    ...:  i=0 
    ...:  while(i<n): 
    ...:   val=yield i 
    ...:   print "value is:",val 
    ...:   i+=1 
    ...: 
In [24]: z1=z(10) 
In [25]: z1.next() 
Out[25]: 0 

In [26]: z1.send(5) # I was expecting that after "send", output value will become "5" 
value is: 5 
Out[26]: 1 

In [27]: z1.next() 
value is: None # I was expecting that z1.next() will restart from "6" because I sent "5" 
Out[27]: 2 

Eh bien, je suppose que j'avais mal comprendre vraiment ce que « envoyer » ne , comment le corriger?

Répondre

6

Vous générez i mais vous ne lui attribuez pas la valeur de retour de yield. Si vous attribuez la valeur de retour, vous verrez la sortie que vous attendez:

def z(n): 
    print 'Generator started' 
    i=0 
    while(i<n): 
     val=yield i 
     print "value is:",val 
     if val is not None: 
      i = val 
     i+=1 

z1=z(10) 
print 'Before start' 
print z1.next() 
print z1.send(5) 
print z1.next() 

Sortie:

Before start 
Generator started 
0 
value is: 5 
6 
value is: None 
7 

Mise à jour: Lorsque send ou next est appelé pour la première fois le générateur est exécuté depuis le début à la première instruction yield à laquelle la valeur de point est renvoyée à l'appelant. C'est pourquoi le texte value is: n'est pas visible au premier appel. Lorsque send ou next est appelée pour la deuxième fois, l'exécution reprend à partir de yield. Si send a été appelé, le paramètre qui lui est donné est renvoyé par l'instruction yield, sinon yield renvoie None.

+0

Si j'utilise simplement z1.next(), il imprime des nombres; lors de l'utilisation de "print z1.next()", l'instruction "value is" apparaît. Pourquoi? – Troskyvs

+0

@Troskyvs Mis à jour répondre un peu, j'espère que cela répond à votre question. – niemmi

+0

Merci, j'ai commencé à comprendre votre point, à l'intérieur du générateur le "val = yield i" signifie que val est mis à partir de la commande "send" externe, tandis que l'appelant externe obtient la valeur de retour de "yield i". C'est vraiment difficile de comprendre pourquoi "next()" est égal à "send (None)" et donc val est "None". – Troskyvs