There's a number of good questions about similar matters, e.g.
python generator "send" function purpose?
What does the "yield" keyword do?
Lets get back to a definition of "send":
Resumes the execution and “sends” a value into the generator function. The value argument becomes the result of the current yield expression. The send() method returns the next value yielded by the generator, or raises StopIteration if the generator exits without yielding another value. When send() is called to start the generator, it must be called with None as the argument, because there is no yield expression that could receive the value
But I feel I am missing something important. Here's my example with 3 send
calls, including the initial one with a None
value just to initialize a generator:
def multiplier():
while True:
m = yield # Line #3
print('m = ' + str(m)) # Line #4
yield str(m * 2) # Line #5
yield str(m * 3) # Line #6
#------------------------
it = multiplier()
print('it.send(None): ')
print(str(it.send(None)))
print('--------------')
print('it.send(10): ')
print(it.send(10))
print('--------------')
print('it.send(100): ')
print(it.send(100))
print('--------------')
And here's an output:
it.send(None):
None
--------------
it.send(10):
m = 10
20
--------------
it.send(100):
30
--------------
Questions:
What happens exactly when I use
it.send(10)
in a line #5. If we follow the definition, the generator execution resumes. Generator accepts10
as input value and uses it in a currentyield expression
. It isyield str(m * 2)
in my example, but then howm
is set to10
. When did that happen. Is that because of the reference betweenm
andyield
in a line #3?What happens in a line #6
it.send(10)
and why output is still30
? Does it mean that the reference in my previous question only worked once?
Note:
If I've changed my example and added a line m = yield
between lines #5 and #6 and then use next(it)
after print(it.send(10))
- in that case the output starts to make sense: 20 and 300