Using async/await in Python


I read about the use of async / await in other programming languages ​​and did not quite understand how and when they are used. What are they for? Can they be used to improve existing code? In what cases should they not be used?

PEP 492 introduced support for native coroutines and async / await syntax to Python 3.5. A notable limitation of the Python 3.5 implementation is that it was not possible to use await and yield in the same function body. In Python 3.6 this restriction has been lifted, making it possible to define asynchronous generators:

async def ticker(delay, to):
    """Yield numbers from 0 to *to* every *delay* seconds."""
    for i in range(to):
        yield i
        await asyncio.sleep(delay)

PEP 530 adds support for using async for in list, set, dict comprehensions and generator expressions:

result = [i async for i in aiter() if i % 2]

Additionally, await expressions are supported in all kinds of comprehensions:

result = [await fun() for fun in funcs if await condition()]


See. Async / await is needed in order not to block the execution thread while waiting for some asynchronous event. The Async/await construct essentially turns the procedure into a coroutine (coroutine): it stops its execution for the await time, waits for an asynchronous event, and resumes work.

In the non-async version, the wait turns out to be blocking, or you need to manually do tricks: start the operation and subscribe to its end. Async makes code simpler and more linear.

Example (in pseudocode):


    filename = GetFilename()
    content = await DownloadUrl(url)
    WriteToFile(filename, content)


    filename = GetFilename()
    BeginDownloadUrl(url, onfinished: lambda content: StoreContent(content, filename))

StoreContent(content, filename)
    WriteToFile(filename, content)

You can see that without async, the execution context (local variables, etc.) has to be manually passed to the tail of the function (continuation). If there are a lot of async calls, similar code without async quickly becomes complicated.

An important difference between an async and a synchronous function is that an async function returns to the calling code at the time of the first execution of the await (if it has not yet completed). The calling code can wait until the end of the work with await, or can continue working on its own.

Using async/await makes sense where you have a non-cpu wait. For example, waiting for data to arrive from the Internet, or reading a file from a disk. In this case, you release the physical thread of execution for the system, but logical execution continues (after await returns).

Scroll to Top