Синтаксис async/await в Python — как писать асинхронный код

19 июня 2026
Автор

Антон Ларичев

Введение

Ключевые слова async и await появились в Python 3.5 и стали основным способом написания асинхронного кода. Они делают асинхронный код понятным и читаемым, напоминающим по структуре обычный синхронный код, но позволяющим эффективно работать с операциями ввода-вывода.

В этой статье мы подробно разберём, как использовать async def для объявления корутин, await для ожидания результатов и как строить цепочки асинхронных вызовов на практике.

Объявление корутин с async def

Ключевое слово async перед def превращает обычную функцию в корутину. Корутина — это функция, которая может приостанавливать своё выполнение в определённых точках, уступая управление событийному циклу.

import asyncio

# Обычная функция
def obychnaya_funkciya():
    return "Я синхронная"

# Корутина
async def korutina():
    return "Я асинхронная"

# Вызов обычной функции — сразу возвращает результат
rezultat = obychnaya_funkciya()
print(rezultat)  # Я синхронная

# Вызов корутины — возвращает объект корутины, а не результат
korutina_obj = korutina()
print(korutina_obj)  # <coroutine object korutina at 0x...>

# Для получения результата нужно запустить через событийный цикл
async def main():
    rezultat = await korutina()
    print(rezultat)  # Я асинхронная

asyncio.run(main())

Оператор await и его правила

Оператор await используется для ожидания завершения асинхронной операции. Он может применяться только внутри функции, объявленной как async def.

import asyncio

async def poluchit_dannye():
    print("Запрос данных...")
    # await приостанавливает корутину на 2 секунды
    await asyncio.sleep(2)
    print("Данные получены!")
    return {"id": 1, "imya": "Python"}

async def obrabotat_dannye(dannye):
    print(f"Обработка: {dannye}")
    await asyncio.sleep(1)
    return f"Обработано: {dannye['imya']}"

async def main():
    # Последовательное выполнение с await
    dannye = await poluchit_dannye()
    rezultat = await obrabotat_dannye(dannye)
    print(rezultat)

asyncio.run(main())

Применять await можно только к объектам, которые поддерживают протокол ожидания (awaitable). К ним относятся:

  • Корутины (объекты, возвращённые async def функциями)
  • Задачи (asyncio.Task)
  • Объекты asyncio.Future
  • Любые объекты с методом __await__

Цепочки асинхронных вызовов

В реальных приложениях асинхронные операции часто образуют цепочки — результат одной операции передаётся в следующую.

import asyncio

async def zaprosit_token():
    # Имитируем получение токена авторизации
    await asyncio.sleep(0.5)
    return "token_abc123"

async def zaprosit_profil(token):
    # Имитируем запрос профиля с токеном
    await asyncio.sleep(1)
    return {"token": token, "imya": "Алексей", "rol": "разработчик"}

async def zaprosit_dostup(profil):
    # Имитируем проверку прав доступа
    await asyncio.sleep(0.5)
    return f"Доступ разрешён для {profil['imya']} (роль: {profil['rol']})"

async def main():
    # Цепочка последовательных асинхронных вызовов
    token = await zaprosit_token()
    profil = await zaprosit_profil(token)
    dostup = await zaprosit_dostup(profil)
    print(dostup)

asyncio.run(main())

Если вы хотите детальнее изучить асинхронное программирование и паттерны проектирования в Python — приходите на наш большой курс Продвинутый Python. На курсе 171 урок и 22 упражнения, AI-тренажёры для практики 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.

Параллельное выполнение с await

Когда операции не зависят друг от друга, их можно выполнять параллельно. Сравним последовательный и параллельный подходы:

import asyncio
import time

async def operaciya(nazvanie, zaderjka):
    await asyncio.sleep(zaderjka)
    return f"{nazvanie} выполнена"

async def posledovatelnoe():
    # Каждая операция ждёт предыдущую
    nachalo = time.time()
    r1 = await operaciya("A", 1)
    r2 = await operaciya("B", 2)
    r3 = await operaciya("C", 1)
    print(f"Последовательно: {time.time() - nachalo:.1f} сек")  # ~4 сек
    return [r1, r2, r3]

async def parallelnoe():
    # Все операции запускаются одновременно
    nachalo = time.time()
    r1, r2, r3 = await asyncio.gather(
        operaciya("A", 1),
        operaciya("B", 2),
        operaciya("C", 1),
    )
    print(f"Параллельно: {time.time() - nachalo:.1f} сек")  # ~2 сек
    return [r1, r2, r3]

async def main():
    await posledovatelnoe()
    await parallelnoe()

asyncio.run(main())

Async-контекстные менеджеры

Python позволяет создавать асинхронные контекстные менеджеры с помощью async with. Это полезно для управления ресурсами, которые требуют асинхронной инициализации или очистки.

import asyncio

class AsinhronnoeSoedinenie:
    def __init__(self, adres):
        self.adres = adres

    async def __aenter__(self):
        # Асинхронная инициализация соединения
        print(f"Подключение к {self.adres}...")
        await asyncio.sleep(1)
        print("Соединение установлено")
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        # Асинхронное закрытие соединения
        print("Закрытие соединения...")
        await asyncio.sleep(0.5)
        print("Соединение закрыто")

    async def zapros(self, sql):
        await asyncio.sleep(0.5)
        return f"Результат запроса: {sql}"

async def main():
    async with AsinhronnoeSoedinenie("db://localhost") as conn:
        rezultat = await conn.zapros("SELECT * FROM users")
        print(rezultat)

asyncio.run(main())

Обработка ошибок в асинхронном коде

Обработка исключений в async/await коде работает так же, как в синхронном — через try/except:

import asyncio

async def nestabilniy_zapros():
    await asyncio.sleep(1)
    raise ConnectionError("Сервер недоступен")

async def main():
    try:
        rezultat = await nestabilniy_zapros()
    except ConnectionError as e:
        print(f"Ошибка соединения: {e}")

    # Обработка ошибок при параллельном выполнении
    rezultaty = await asyncio.gather(
        asyncio.sleep(1),
        nestabilniy_zapros(),
        return_exceptions=True,  # Исключения возвращаются как результаты
    )

    for r in rezultaty:
        if isinstance(r, Exception):
            print(f"Задача завершилась с ошибкой: {r}")
        else:
            print(f"Задача выполнена: {r}")

asyncio.run(main())

Частые ошибки

  • Использование await вне async-функции — оператор await работает только внутри корутин. Вызов await в обычной функции приведёт к SyntaxError.
  • Забыть await при вызове корутины — без await вызов async def функции вернёт объект корутины, а не результат. Логика внутри корутины не выполнится.
  • Смешивание синхронного и асинхронного кода — вызов time.sleep() внутри корутины заблокирует весь событийный цикл. Всегда используйте asyncio.sleep() и другие асинхронные аналоги.
  • Слишком глубокие цепочки await — длинные последовательности await без параллелизма сводят на нет преимущества асинхронности. Ищите возможности для параллельного выполнения через gather() или create_task().

Частозадаваемые вопросы

Можно ли использовать await в лямбда-выражениях? Нет, Python не поддерживает async lambda. Если вам нужна короткая асинхронная функция, объявите её как обычную корутину через async def.

Чем async for отличается от обычного for? async for используется для итерации по асинхронным итераторам — объектам, которые реализуют метод __aiter__ и __anext__. Обычный for работает только с синхронными итераторами.

Работает ли async/await с многопоточностью? Да, вы можете комбинировать asyncio с потоками через asyncio.to_thread() для запуска блокирующих функций. Однако корутины сами по себе выполняются в одном потоке.

Заключение

Синтаксис async/await делает асинхронный код в Python интуитивным и легко читаемым. Понимание того, как объявлять корутины, ожидать результаты и строить параллельные цепочки вызовов, — фундамент для работы с любыми асинхронными библиотеками и фреймворками. Для закрепления навыков async/await и глубокого понимания асинхронных паттернов рекомендуем курс Продвинутый Python. В первых 3 модулях курса доступно бесплатное содержание, что позволяет освоить базовые концепции и понять структуру курса до покупки полного доступа.

Стрелочка влевоМодуль asyncio в Python — основы асинхронного программированияБиблиотека aiohttp в Python — асинхронные HTTP-запросыСтрелочка вправо

Постройте личный план изучения Python до уровня Middle — бесплатно!

Python — часть карты развития Backend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Все гайды по Python

Как отправлять запросы с помощью requests в PythonПочему Python выводит значение без команды printКак работает команда print в PythonВозможности Python для автоматизации задачРабота с JSON в Python на примерахPython get — методы получения данныхКак находить и исправлять ошибки в PythonРабота с данными через API и внешние сервисыСтруктура и оформление кода PythonОсновы Django с PythonПолезные приёмы в Python для повседневной работыИспользование locals в Python для отладкиИнтеграция PHP и PythonКак выполнять HTTPS-запросы в PythonFastAPI Python — быстрый старт: создание REST API с нуляКак работать с API в Python
Ввод целого числа в PythonВедение логов в PythonУдаление данных в Python с помощью removeОбработка исключений с помощью try/except в PythonФункция super() в Python — как вызвать метод родителяСоздание собственных контекстных менеджеров в PythonРабота с символами программирования PythonРабота с переменной X в PythonРабота с классами в PythonКак скачать Python на компьютерПростая программа на Python для начинающихОсновы Python для тех, кто начинаетЧто нового в Python 3Поддерживается ли Python 2 и стоит ли его использоватьPython 1 — с чего начиналась история языкаКоманда python print - полное руководство по выводу данныхПравила именования переменных в PythonПользовательские исключения в PythonОсновы Python coreОписание объектов PythonМножественное наследование в Python — примеры и MROНаследование классов в Python — основы и примерыКонтекстный менеджер with в Python — как работает и зачем нуженКомментарии в Python — однострочные, многострочные и docstringКакой Python выбрать для установкиКак вывести целое число с помощью print в PythonКак установить Python на Windows macOS и LinuxКак пользоваться консолью PythonКак получить последний элемент в PythonКак найти значение в PythonКак настроить PythonКак использовать print для строк в PythonКак работает интерпретатор PythonИнструкция по работе с PythonБлок finally в обработке исключений PythonЦелые числа в PythonАбстрактные классы в Python — ABC и abstractmethod
Загрузка данных PythonУправление проектами на GitHub с PythonСоздание веб-приложений на Flask PythonСоздание бота на PythonСоздание интерфейсов Python QTСоздание игр с PygameСоздание GUI в PythonКак работать со словарями в PythonРабота с библиотеками через Python PackagingРабота со временем в Python при помощи модуля timePython name — особенности переменнойМатематические операции в Python с модулем mathPython listing — что это и как использоватьPytest — тестирование на Python: полное руководствоОбработка изображений с OpenCV PythonNumPy в Python — основы и применение в задачахМашинное обучение с PythonИспользование Anaconda с PythonМодуль contextlib в Python — утилиты для контекстных менеджеровБиблиотеки Python и их применение в проектах
Возврат значений из функции в PythonВложенные функции в PythonСоздание собственных декораторов в PythonРабота с функцией map в PythonЦикл while в Python и примеры использованияОбработка чисел, введённых через input в PythonОсновные операторы в Python с примерамиУсловные выражения if else в Python для начинающихКак выполняется вызов функций call в PythonПродвинутые генераторы в Python — send, throw, close и корутиныПозиционные и именованные аргументы в PythonОбъявление переменных и управление областью видимости в PythonПередача аргументов по ссылке и по значению в PythonПередача аргументов через args и kwargs в PythonОсновные методы Python и примеры их использованияОператор match/case в Python 3.10+ — основы структурного сопоставленияПаттерны match/case в Python — деструктуризация, guard и вложенные шаблоныПрактические примеры match/case в Python — реальные сценарии примененияЛокальные и глобальные переменные в PythonЧасто используемые команды PythonКлючевые слова global и nonlocal в PythonКак создавать функции в PythonКак работает сборщик мусора в PythonКак работает область видимости переменных в PythonКак работает функция callable в PythonКак работает функция any и all в PythonКак проверить тип переменной в PythonКак передать функцию как аргумент в PythonКак использовать функцию isinstance в PythonКак использовать функцию filter в PythonКак использовать функцию filter в PythonКак использовать функцию eval безопасно в PythonКак использовать декораторы в PythonИзменяемые и неизменяемые типы данных в PythonГенераторы и yield в Python — как создавать и использоватьГенераторные выражения в Python — синтаксис и примерыФункции в Python и способы их вызоваФункции как объекты в PythonЧто такое замыкания в PythonЧто делает функция reduce в PythonЧто делает функция id в PythonАргументы по умолчанию в PythonАнонимные функции и lambda в PythonАлгоритмы на Python — примеры и объяснение
Запись данных в PythonУстановка pip в PythonУправление зависимостями requirement в PythonУправление библиотеками с помощью Python PackagingУдаление пробелов с помощью strip в PythonСтруктурирование кода в PythonСоздание исполняемого файла Python в exeРазбор traceback в модуле PythonРазбор site-packages в PythonРазбор Program Files в PythonРабота с Unicode кодировками в PythonРабота с системными функциями Python sysРабота с папкой AppData в PythonРабота с модулем logging в PythonРабота с каталогами в PythonРабота с CSV в PythonВиртуальная среда venv в Python — создание и настройкаКак создать простое приложение на PythonИспользование pip в Python для установки пакетовМодули в Python и организация кода в проектеИмпорт модулей в Python и правила подключенияРабота с файлами в Python пошаговоЧто делает компилятор Python и как он работаетПолучение строки из модуля PythonПодключение файлов в Python с includeПеременные среды в PythonСборка проекта с помощью packaging в PythonНастройка Python сервераИспользование Python на UbuntuИспользование консоли PythonИспользование кодировок в PythonИнициализация пакетов PythonИмпорт модулей PythonИмпорт имен в PythonСреда IDLE Python и базовые возможностиЧтение и запись TXT в PythonЧтение файлов в Python с помощью open file
Удаление элементов из списка PythonТипы данных в Python — обзор и рекомендацииОсновные операции со строками в PythonМетоды str в Python и обработка текстаСписки в Python и их ключевые методыСоздание списков данных в PythonРабота со строками и символами в PythonРабота со столбцами в PythonРабота со списком значений в PythonРабота с таблицами в Python с помощью DataFrameРабота с RFR в PythonРабота с пробелами в PythonРабота с массивами в PythonРабота с кортежами tuple PythonРабота с координатами X и Y в PythonРабота с ключами в PythonРабота с элементами данных PythonРабота с двоичными числами PythonРабота с данными в PythonРабота с данными NumPy PythonРабота с большими числами в PythonРабота с битами в PythonРабота с байтами в PythonЧто такое значение в Python и как его определитьМножества в Python и операции с нимиИспользование range в Python для цикловПроверка на четность в PythonПроверка числа в PythonПреобразование типов в PythonПреобразование списка в строку PythonПреобразование числа в строку в PythonПостроение графиков в PythonОпределение индекса элемента в PythonОкругление чисел в PythonОбъединение списков в Python с помощью zipМножества в PythonМассивы в Python и отличие от списковМассив чисел в PythonКортежи данных в PythonКак вычислить сумму чисел в PythonКак получить остаток от деления в PythonКак найти следующее число в PythonИспользование Unicode в PythonТип int в Python и его особенностиИндекс списка в PythonФункции для работы со строками в PythonЭлементы Python и способы доступа к нимДоступ к элементам массива в PythonДеление чисел в PythonРабота с данными в Python на практикеКак работать с числами в Python
Открыть базу знаний

Лучшие курсы по теме

Иконка молнииНовый
изображение курса

Основы Python

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Nest.js с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.6
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Docker и Ansible

Антон Ларичев
AI-тренажерыAI-тренажеры
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий