Sending values into generators in Python : Purpose of the `send` method
Python generators are basically a two-way street i.e. you can yield value from them, and you can send some value into them as well. This ability of generators to pause at yield with keeping states saved, and resume later is the whole basis of doing asynchronous programming in Python. The newly introduced async-await syntax (in Python 3.5) is also based on it; moreover, async
is the new intuitive way of creating coroutines (instead the types.coroutine
/asyncio.coroutine
decorators), and await
is just a syntactic sugar for yield from
.
Now, to explain what the send
method does in a generator, let's take an example generator:
(just to note, i'll be using Python 3.7 in all these examples)
def foobar(): for num in range(10): yield num
the generator simply yields one value between 0-9 at a time to the caller:
>>> gen = foobar() >>> next(gen) 0 >>> next(gen) 1
Now, what if we use send
some value (None
for now) for the sake of fun:
gen.send(None) 2 gen.send(None) 3
This does not seem to do anything special, we're getting the next values i.e. it behaves exactly like next
, so where's the magic?
Before moving forward, one thing to note that, gen.send(None)
is exactly similar to next(gen)
.
To get the magic of send
, we need to re-define the generator like:
Comments