Перейти к основному содержимому
Средний уровень Python2026-07-29 · 11 мин чтения

Python async / await Объяснение: руководство 2026 г.

Асинхронность в Python имеет репутацию запутанной системы. Это не обязательно. Как только вы усвоите одно предложение — async позволяет ОДНОМУ потоку выполнять несколько чередующихся задач, связанных с вводом-выводом — всё остальное следует за ним.

В этом руководстве рассказывается: что на самом деле делают async def и await, когда побеждает async, а когда это неправильный инструмент, четыре шаблона, которые использует каждая асинхронная кодовая база (последовательный, сбор, семафор, тайм-аут), и три способа, которыми новички молча проглатывают ошибки.

Ментальная модель, состоящая из одного предложения

Асинхронность в Python — это совместный параллелизм в одном потоке. Когда ваш код нажимает «await», управление возвращается в цикл событий, который может запустить другую задачу, пока первая ожидает ввода-вывода. Когда ввод-вывод завершается, цикл возобновляет выполнение первой задачи с того места, где он был приостановлен.

Вот и все. Никаких потоков, никаких процессов, никакого параллелизма (в смысле CPython с GIL). Всего один поток, совмещающий множество задач, которые большую часть времени проводят в ожидании в сети/на диске/базе данных.

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

Трехстрочная минимально жизнеспособная асинхронная программа

▶ PYTHONeditable · runs in your browser
  • async def hello() — объявляет сопрограмму. Вызов hello() не запускает код; он создает объект сопрограммы.
  • await asyncio.sleep(1) — возвращает управление циклу событий на 1 секунду.
  • asyncio.run(hello()) — создает цикл событий и запускает сопрограмму до завершения.

Правило: `await` только внутри `async def`. Вызов await в обычной функции является синтаксической ошибкой.

Когда побеждает асинхронность (а когда нет)

Async побеждает: работа, связанная с вводом-выводом

Любая задача, которая тратит большую часть времени на ОЖИДАНИЕ, является кандидатом на асинхронность:

  • HTTP-запросы (внешние API, парсинг, веб-перехватчики)
  • Запросы к базе данных
  • Файл читает/пишет
  • потоки WebSocket/gRPC
  • Потребители очередей (Redis, RabbitMQ, Kafka)

Пример: получение 100 URL-адресов.

▶ PYTHONeditable · runs in your browser

Ускорение настенных часов в 50–100 раз для работы с интенсивным вводом-выводом. Именно здесь асинхронность зарабатывает свой бюджет сложности.

Async LOSES: работа с загрузкой процессора

Async не обеспечивает параллелизма вычислений. Поскольку он является кооперативным однопоточным, цикл «горячего» процессора блокирует весь цикл событий.

▶ PYTHONeditable · runs in your browser

Все остальные задачи «зависают», пока работает pbkdf2. Для работы с привязкой к процессору используйте «многопроцессорность» или «concurrent.futures.ProcessPoolExecutor», а не асинхронность.

Смешанная рабочая нагрузка: run_in_executor

Если ОДИН шаг нагружает ЦП, а остальные — ввод-вывод, оберните шаг ЦП так, чтобы он выполнялся в пуле потоков, не блокируя цикл:

▶ PYTHONeditable · runs in your browser

None = пул потоков по умолчанию. Отлично подходит для вызова сторонних библиотек синхронизации, которые работают медленно, но их нельзя переписать.

Четыре шаблона

1. Последовательный — по одной задаче за раз

▶ PYTHONeditable · runs in your browser

Используйте, когда каждый запрос зависит от результата предыдущего.

2. asyncio.gather — запустить все сразу

▶ PYTHONeditable · runs in your browser

Выбор по умолчанию для независимых задач ввода-вывода. Но: если вы соберете 10 000 задач для одного API, вы получите файловые дескрипторы с ограничением скорости или исчерпывающим числом операций. Вот здесь-то и появляется шаблон семафора.

3. Семафор — ограничение параллелизма

▶ PYTHONeditable · runs in your browser

asyncio.Semaphore(N) позволяет не более N задачам пройти мимо async with sem: в любой момент. Остальные задачи стоят в очереди. Используйте для любого внешнего API с ограничением скорости или базы данных с пулом соединений.

4. Таймаут — отказаться от медленной работы

▶ PYTHONeditable · runs in your browser

asyncio.wait_for отменяет базовую задачу через N секунд. Важно для любого асинхронного кода, который взаимодействует с сетью — никогда не делайте неограниченное ожидание.

Три ловушки, допускающие ошибки

Ловушка 1: asyncio.gather с return_Exceptions=True

▶ PYTHONeditable · runs in your browser

Полезно, если вы хотите сохранить частичные результаты, но СМЕРТЕЛЬНО, если вы не проверяете каждый результат:

▶ PYTHONeditable · runs in your browser

Без проверки ошибки молча исчезают.

Ловушка 2: задачи «выстрелил и забыл»

▶ PYTHONeditable · runs in your browser

Если background_work() вызывается, Python выдает предупреждение при завершении работы и продолжает работу. Если вас что-то волнует, сохраните задачу и «ожидайте» ее или используйте «asyncio.TaskGroup» (3.11+), который распространяет все ошибки.

Ловушка 3: код синхронизации внутри async

▶ PYTHONeditable · runs in your browser

запросы синхронны. Даже внутри async def, requests.get блокирует весь цикл до тех пор, пока не придет ответ. Используйте httpx (или aiohttp) для асинхронного HTTP.

Правило: никогда не используйте библиотеку синхронного ввода-вывода внутри асинхронного кода. Если у библиотеки нет асинхронного варианта, оберните ее в run_in_executor.

asyncio.TaskGroup — способ разветвления 2026 года

В Python 3.11 добавлена TaskGroup, которая четко решает проблему «выстрелил и забыл»:

▶ PYTHONeditable · runs in your browser

Структурированный параллелизм — ни потерянных ошибок, ни потерянных задач. Предпочитайте это вместо простого create_task в современном коде.

Пример из реальной жизни: парсер с ограниченной скоростью

▶ PYTHONeditable · runs in your browser

Все четыре шаблона в 15 строках: ограниченный параллелизм (семафор), таймауты (wait_for), явные ветки ошибок (без поглощения) и сборка для разветвления. Скопируйте и вставьте эту фигуру в любую задачу асинхронного ввода-вывода.


Асинхронность в Python требует серьезного обучения, но мысленная модель проста: один поток, совместные паузы в ожидании, ввод-вывод перекрывается. Освойте gather + Semaphore + wait_for + TaskGroup, и вы выполните 95 % асинхронной работы, которую когда-либо писали.

Следующий шаг: Старший курс Python содержит 20 практических уроков по asyncio, TaskGroup, aiohttp/httpx и описанным выше шаблонам параллелизма — при этом настоящий Python работает в вашем браузере.

Готовы попробовать?

15 уроки бесплатно после бесплатной регистрации — без карты. Попробуйте платформу, а затем принимайте решение.

Начни бесплатно →

Or unlock every lesson

Pro — $12/mo, unlimited AI, cancel any time. Refund within 14 days worldwide.

See Pro plans →

Get one Python lesson + one career idea every Friday

No spam, no "buy our course now". Three bullets, every Friday. Unsubscribe with one click.