Урок курса

Async и await в Python: основы asyncio

Python для профессионалов

Асинхронность помогает одной программе обслуживать много ожидающих I/O-операций: HTTP-запросов, сокетов, очередей и таймеров. Функция async def при вызове возвращает coroutine object; код начинает выполняться, когда корутину запускает event loop.

import asyncio

async def fetch_stub(name: str) -> str:
    await asyncio.sleep(0.2)
    return f"done: {name}"

async def main():
    results = await asyncio.gather(
        fetch_stub("a"),
        fetch_stub("b"),
    )
    print(results)

asyncio.run(main())

await приостанавливает текущую корутину и отдаёт управление циклу событий, пока ожидаемая операция не будет готова.

Конкурентность не равна параллелизму

Event loop обычно работает в одном потоке. Он быстро переключается между задачами в точках await, поэтому время ожидания одной сети используется для обслуживания другой. Это конкурентность. CPU-тяжёлый цикл Python не ускорится и, наоборот, заблокирует остальные корутины.

Асинхронная программа полезна, если библиотека тоже предоставляет неблокирующий API. Вызов обычного requests.get или time.sleep внутри async def остановит loop. Используйте асинхронный HTTP-клиент и asyncio.sleep, а блокирующую функцию при необходимости выносите через asyncio.to_thread.

Не ставьте await перед задачами по очереди, если они независимы: тогда конкурентность исчезает. Создавайте ограниченную группу задач и учитывайте лимиты внешнего сервиса.

Ошибки и управление задачами

У каждой созданной задачи должен быть владелец, который дождётся результата и обработает исключение. Бесконтрольный create_task может оставить «осиротевшую» работу. Для структурированной конкурентности в современных версиях Python используют asyncio.TaskGroup.

Добавляйте таймауты, отмену и лимит одновременных операций через semaphore. Отмена доставляется как CancelledError; очистку ресурсов помещайте в finally или асинхронный контекстный менеджер.

Asyncio оправдан для множества I/O-bound операций. Для численных CPU-bound расчётов выбирают процессы, нативные библиотеки или распределённое выполнение. Начинайте с синхронного кода, если нагрузка мала: асинхронность добавляет отдельную модель ошибок и тестирования.

Задача 1

Что происходит, когда корутина ожидает неблокирующую I/O-операцию через await?

Выберите один вариант
Без регистрации · результат не сохраняется

Продолжить с сохранением прогресса

Перейдите к уроку в учебном кабинете.

Перейти к интерактивному уроку