← Назад к вопросам

Как работает асинхронный генератор в 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, а не значение.

Как они работают

  1. Ленивое вычисление: значения не генерируются до момента запроса, что экономит память
  2. Асинхронные операции: внутри генератора можно использовать await для асинхронных вызовов
  3. Поддержка асинхронной итерации: используются с 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

Практические применения

  1. Потоковая обработка данных — обработка больших наборов данных частями
  2. API клиенты — загрузка данных постепенно с паузами
  3. Мониторинг и логирование — генерация событий по мере их возникновения
  4. 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)

Асинхронные генераторы — это элегантный способ работать с асинхронными потоками данных, позволяя писать чистый и читаемый код.

Как работает асинхронный генератор в Python? | PrepBro