I am trying to understand some of the subtle details of python generators. One of the test programs I wrote to see if I could both send and read alternatively values to/from the same generator is the following:
def injector():
while True:
try:
print 'a'
v = yield
print 'b', v
yield v
print 'c'
except GeneratorExit:
print 'exit'
break
g = injector()
print 'send none'
g.send(None)
print 'send 2'
g.send(2)
print 'receiving'
v = g.next()
print 'received', v
g.close()
The expected output for this program is:
send none
a
send 2
b 2
receiving
received 2
c
a
exit
The output I get is:
send none
a
send 2
b 2
receiving
c
a
received None
exit
Now, obviously, the question is why am I getting the above output ? What is it that I did not understand about how generators work ?
Let me try to clarify:
Here the coroutine is started. It executes until the first yield whose result is returned from
.send(), but then discarded.The coroutine prints
aand yields nothing, thusNone. So it is ok to discard.Here you send a 2 to the coroutine, making it continue where you left it.
v = 2.It prints
2and yieldsvagain. You would expect that from theg.send()call.So after receiving and discarding
v, you doHere you give control to the coroutine again, which prints
c, thena, then yieldsNoneagain, which you get here.thus prints
Noneforv.What you probably want is
(Note that this last block can be written more cleanly and nicely as follows:
)