2016-12-01 6 views
4

Я пытаюсь функция отправки генератора, я ожидал, что посыл изменит значение, бытие выхода, поэтому я попытался в IPython:Метод отправки «python» не меняет значение «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 

Ну, я полагаю, что было неправильное понимание того, что «отправить» действительно , как исправить?

ответ

6

Вы получаете i, но вы не назначаете возвращаемое значение из инструкции yield. Если присвоить возвращаемое значение, которое вы будете видеть вывод, что вы ожидаете:

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() 

Выход:

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

Update: Когда send или next вызывается в первый раз, генератор выполнен с самого начала к первому оператору yield, значение которого возвращается вызывающему абоненту. Вот почему текст value is: не отображается при первом вызове. Когда send или next вызывается во второй раз, выполнение выполняется с yield. Если send был вызван, данный ему параметр возвращается оператором yield, в противном случае yield возвращает None.

+0

Если я просто использую z1.next(), он печатает числа; при использовании «print z1.next()» появляется инструкция «value is». Зачем? – Troskyvs

+0

@Troskyvs Обновленный ответ немного, надеюсь, что ответит на ваш вопрос. – niemmi

+0

Спасибо, я начал понимать вашу точку, внутри генератора «val = yield i» означает, что val устанавливается из внешней команды «send», а внешний вызывающий абонент получает возвращаемое значение из «yield i». Это очень сложно понять, почему «next()» равно «send (None)», и, таким образом, val является «None». – Troskyvs