Короткий ответ
Асинхронный генератор — функция async def с yield внутри, которая поддерживает await в процессе генерации значений и итерируется через async for, позволяя лениво producing данные, зависящие от асинхронных операций.
Как это работает подробнее
В отличие от обычного генератора, асинхронный генератор возвращает объект с методом __anext__ (корутину); async for автоматически await-ит каждый __anext__ и обрабатывает StopAsyncIteration при завершении, позволяя использовать await между yield.
Пример кода
example-275.py
import asyncio
async def paginated_items(total_pages):
for page in range(total_pages):
await asyncio.sleep(0.1) # имитация запроса следующей страницы к API
yield f"page-{page}-data"
async def main():
async for item in paginated_items(3):
print(item)
asyncio.run(main())
# Проверка: элементы выводятся по одному с задержкой ~0.1с между ними, а не все сразуЧто использовать на практике
- Практика. Полезен при постраничной выгрузке данных из внешнего API или БД с асинхронным драйвером, стриминге результатов по частям без загрузки всего набора данных в память сразу.
Подводные камни
- Риски. Пытаются использовать обычный
forвместоasync forна асинхронном генераторе — получают ошибку; смешивают синхронный и асинхронный генератор в одной функции, что приводит кSyntaxErrorили логическим ошибкам.