Back to the Future with Async and Await in Python 3.5
By Idego Group

This article explores Python 3.5's new asynchronous programming features. The async and await syntax simplifies writing cooperative, non-blocking code compared to earlier generator-based approaches using @asyncio.coroutine decorators with yield from expressions.
The traditional approach used @asyncio.coroutine decorators with yield from expressions. While functional, this syntax proved less intuitive for developers unfamiliar with generator patterns. The new syntax replaces these constructs with more readable async def function definitions and await expressions.
Both approaches accomplish the same goal—managing multiple I/O operations efficiently within a single thread via an event loop—but with improved clarity. Fetching three URLs concurrently completes in roughly three seconds rather than the six-plus seconds sequential execution would require.
However, the two syntactic styles cannot be mixed directly. Functions defined with async def cannot use yield from, and generator-based coroutines cannot use await. Developers must choose one approach consistently.
Beyond basic syntax, Python 3.5 introduces async iteration protocols through async for loops and asynchronous context managers via async with statements. These features explicitly delineate where execution can suspend, making control flow transparent.
While syntactic sugar alone might seem minor, these changes represent substantial infrastructure supporting asynchronous programming in Python's future, potentially accelerating adoption of Python 3 over legacy versions.