Search code examples
pythongeneratoryield

Why the yield return value is changed that way?


def h():  
    print 'Wen Chuan',
    m = yield 5 # Fighting!  
    print m  
    d = yield 12  
    print 'We are together!'  
c = h()  
m = c.next() #m gets the value of yield 5
d = c.send('Fighting!') #d gets the value of yield 12
print 'We will never forget the date', m, '.', d

Please check above code. It's running result is below:

>>> ================================ RESTART ================================
>>> 
Wen Chuan Fighting!
We will never forget the date 5 . 12

And according to my understanding, the first yield return value is changed to "Fighting!" already, but why later when print m it still shows value 5?


Solution

  • No, you are not changing what the yield 5 expression makes the generator produce.

    .send() will change what the local m inside h() will be set to only.

    What happens is:

    • You create h(), a generator function, and execution is frozen.
    • You call .next() on the generator. Execution is resumed, 'Wen Chuan' is printed and the code runs until the yield 5 expression. 5 is returned and assigned to the global m. The generator is paused again.
    • You call c.send('Fighting!'). Execution is resumed, 'Fighting!' is assigned to the local variable m in the generator function, print m prints that. yield 12 is executed, the generator is paused and 12 is assigned to the global variable d.
    • 'We will never forget the date', 5, '.', 12 is printed.

    By this point the generator function is still paused, and the last line of the generator function is never executed. If you were to call .next() again, then 'We are together!' would be printed, the generator end and StopIteration would be raised.