В чем назначение ключевых слов async и await в Python

«В чем назначение ключевых слов async и await в Python» — вопрос из категории Асинхронность, который задают на 22% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

  • async def: Объявляет функцию как корутину (coroutine). Это особый тип функции, выполнение которой можно приостановить и возобновить.
  • await: Приостанавливает выполнение корутины и передает управление обратно в цикл событий (event loop). Код продолжит выполняться только после завершения ожидаемой операции (например, получения ответа от сервера).

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

Пример с asyncio:

import asyncio
import time

async def fetch_data(delay):
    print("Начало загрузки данных...")
    # Имитация долгой сетевой операции
    await asyncio.sleep(delay)
    print(f"Данные загружены за {delay} сек.")
    return {"data": f"some_data_from_{delay}s_request"}

async def main():
    start_time = time.time()

    # Запускаем обе корутины конкурентно, не дожидаясь завершения каждой по очереди
    task1 = asyncio.create_task(fetch_data(2))
    task2 = asyncio.create_task(fetch_data(3))

    # Ожидаем завершения обеих задач
    result1 = await task1
    result2 = await task2

    end_time = time.time()
    print(f"Все операции завершены за {end_time - start_time:.2f} сек.")

# Запуск главной асинхронной функции
asyncio.run(main())

# Вывод будет примерно таким:
# Начало загрузки данных...
# Начало загрузки данных...
# Данные загружены за 2 сек.
# Данные загружены за 3 сек.
# Все операции завершены за 3.01 сек. (а не за 2+3=5 сек)

Важно: await можно использовать только внутри функции, объявленной с помощью async def.