Ответ
Асинхронный генератор — это функция, которая сочетает в себе поведение генератора (yield) и асинхронной корутины (async/await). Это позволяет создавать итераторы, которые могут приостанавливать свое выполнение не только для выдачи значения, но и для ожидания завершения асинхронной операции.
Объявляется с помощью async def и использует yield для возврата значений.
Ключевые особенности:
- Итерация: Перебор значений осуществляется с помощью цикла
async for. - Асинхронные вызовы: Внутри генератора можно использовать
awaitдля вызова других корутин. - Отложенные вычисления: Как и обычные генераторы, они производят значения «лениво», по одному за раз.
Пример:
import asyncio
# Асинхронный генератор, который имитирует
# получение данных из сети с задержкой.
async def fetch_data_stream(count: int):
for i in range(count):
# Имитация асинхронного I/O-запроса
await asyncio.sleep(0.5)
yield f"Chunk #{i + 1}"
async def main():
print("Starting data stream...")
# Используем async for для итерации по асинхронному генератору
async for chunk in fetch_data_stream(3):
print(f"Received: {chunk}")
asyncio.run(main())
Основное отличие от обычного генератора: Возможность выполнять await между операциями yield, что идеально подходит для работы с потоковыми данными, веб-сокетами или постраничной загрузкой из API.
Ответ 18+ 🔞
Слушай, а вот есть же такая штука — асинхронный генератор. Ну, это типа обычный генератор, который умеет yield, но при этом ещё и асинхронный, как корутина, со своими async/await. Представь: он может не только по одному значению выдавать, но и между выдачами спокойно ждать, пока какая-нибудь асинхронная хуйня завершится. Вообще удобно, блядь.
Что он умеет, этот хитрожопый зверь:
- Итерироваться — но только через
async for, обычныйforтут обосрётся и ничего не поймёт. - Ждать асинхронщину — внутри можно
awaitвпендюрить сколько душе угодно. - Лениво работать — как и любой приличный генератор, не грузит всё в память сразу, а выдаёт по кусочку, когда попросят.
Вот смотри, как это выглядит на практике:
import asyncio
# Асинхронный генератор, который прикидывается, что тянет данные из сети
async def fetch_data_stream(count: int):
for i in range(count):
# Притворяемся, что ждём ответ от сервера
await asyncio.sleep(0.5)
yield f"Chunk #{i + 1}"
async def main():
print("Starting data stream...")
# Итерируемся по нему через async for — по-другому нихуя не получится
async for chunk in fetch_data_stream(3):
print(f"Received: {chunk}")
asyncio.run(main())
И главное, блядь, отличие от простого генератора: он между выдачами значений может вставить await и спокойно ждать, пока там сокет ответит или база данных отпишется. Идеально для стримов, веб-сокетов или когда тебе нужно постранично данные из API тащить, не блокируя весь мир. Ёпта, гениально же!