← Назад к вопросам
Как работает асинхронный генератор в Python?
2.7 Senior🔥 51 комментариев
#Python Core#Асинхронность и многопоточность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# Асинхронные генераторы в Python
Асинхронный генератор — это функция, определённая с помощью async def, которая содержит одно или несколько выражений yield. Это мощный инструмент для создания асинхронных последовательностей данных, которые вычисляются лениво, один элемент за раз.
Основные характеристики
Синтаксис и определение:
async def async_gen():
yield 1
await asyncio.sleep(1)
yield 2
Функция автоматически становится асинхронным генератором, когда содержит yield. При вызове она возвращает объект async_generator, а не значение.
Как они работают
- Ленивое вычисление: значения не генерируются до момента запроса, что экономит память
- Асинхронные операции: внутри генератора можно использовать
awaitдля асинхронных вызовов - Поддержка асинхронной итерации: используются с
async forиasync with
Пример использования
import asyncio
async def fetch_data(urls):
"""Асинхронный генератор для загрузки данных"""
for url in urls:
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
data = await response.json()
yield data # Отправляем данные потребителю
await asyncio.sleep(1) # Имитация задержки
# Использование
async def main():
urls = [http://api.example.com/1, http://api.example.com/2]
async for data in fetch_data(urls):
print(data) # Обрабатываем каждый результат по мере поступления
asyncio.run(main())
Отличие от обычных генераторов
| Генератор | Асинхронный генератор |
|---|---|
yield в обычной функции | yield в async def |
Использует for item in gen() | Использует async for item in gen() |
Нельзя использовать await | Можно использовать await |
| Синхронная итерация | Асинхронная итерация |
Методы асинхронного генератора
async def my_gen():
yield 1
yield 2
agen = my_gen()
await agen.__anext__() # Получить следующий элемент (1)
await agen.__aenter__() # Контекстный менеджер
await agen.__aexit__() # Закрытие генератора
Контекстный менеджер для асинхронного генератора
Можно использовать async with для автоматического закрытия:
from contextlib import asynccontextmanager
@asynccontextmanager
async def managed_gen():
print("Вход")
try:
yield resource
finally:
print("Выход")
await cleanup(resource)
async with managed_gen() as resource:
# работаем с resource
Практические применения
- Потоковая обработка данных — обработка больших наборов данных частями
- API клиенты — загрузка данных постепенно с паузами
- Мониторинг и логирование — генерация событий по мере их возникновения
- WebSocket и real-time — отправка данных клиентам по мере готовности
Обработка ошибок
async def safe_gen():
try:
yield 1
yield 2
except GeneratorExit:
# Генератор закрывается
print("Генератор закрыт")
except Exception as e:
print(f"Ошибка: {e}")
raise
async for item in safe_gen():
print(item)
Асинхронные генераторы — это элегантный способ работать с асинхронными потоками данных, позволяя писать чистый и читаемый код.