Skip to main content

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

Comments powered by Disqus