Skip to main content
An asynchronous generator function is a function defined using async def that contains one or more yield expressions. When called, it does not execute the function body; instead, it returns an asynchronous generator object. It combines the state-suspension capabilities of standard generators with the non-blocking execution of asynchronous programming, allowing the function to await awaitables between yield statements. Unlike a coroutine function (which returns a coroutine object implementing __await__), an asynchronous generator function returns an asynchronous generator object implementing __aiter__ and __anext__.

Syntax and Mechanics

An asynchronous generator function relies on two primary keywords:
  1. async def: Declares the asynchronous function. The presence of a yield statement inside the body instructs the Python parser to classify it strictly as an asynchronous generator function rather than a coroutine function.
  2. yield: Suspends the function’s execution, emits a value to the caller, and preserves the local state for resumption.

The Asynchronous Iterator Protocol

Under the hood, the returned asynchronous generator object implements the Asynchronous Iterator Protocol (PEP 525):
  • __aiter__(self): Returns the asynchronous generator object itself.
  • __anext__(self): Returns an awaitable that, when awaited, executes the generator’s body until the next yield expression. If the generator terminates, the awaitable raises a StopAsyncIteration exception.

Consumption

Because __anext__ returns an awaitable, asynchronous generators cannot be consumed using standard for loops or the next() built-in. They must be consumed within an asynchronous context using async for or the anext() built-in (introduced in Python 3.10).

Bidirectional Communication

Like standard generators, asynchronous generators support bidirectional communication, allowing the caller to send data or exceptions back into the suspended generator. These methods return awaitables:
  • asend(value): Resumes the generator and evaluates the yield expression to value.
  • athrow(type, [value, [traceback]]): Raises an exception at the point where the generator is suspended.
  • aclose(): Raises a GeneratorExit exception at the yield expression, forcing the generator to terminate and run any pending finally blocks.

Technical Constraints

  • No Return Values: An asynchronous generator function cannot contain a return value statement. It may only use an empty return statement, which immediately raises StopAsyncIteration to terminate the generator.
  • Event Loop Dependency: Because it utilizes await, the generator’s execution is strictly bound to a running asynchronous event loop (e.g., asyncio.run()).
  • Yield From: The yield from syntax is not supported in asynchronous generators. To yield values from another asynchronous generator, you must use an explicit async for loop.
Tired of Poor Python Skills? Fix That With Deep Grasping!Learn More