В чем разница между async def и def в Python?

Ответ

Ключевое различие — в модели выполнения: def создает синхронные функции, а async def — асинхронные корутины (coroutine).

def (Синхронная функция)

  • Выполнение: Блокирующее и последовательное. Если функция выполняет долгую операцию (например, сетевой запрос), она блокирует весь поток до своего завершения.
  • Вызов: Обычный прямой вызов: result = my_function().

async def (Асинхронная корутина)

  • Выполнение: Неблокирующее. Может приостановить свое выполнение в точке await, передав управление обратно циклу событий (event loop). Это позволяет выполнять другие задачи, пока корутина ждет завершения долгой I/O-операции (например, ответа от сервера).
  • Вызов: Требует await внутри другой async функции: result = await my_coroutine(). Простой вызов my_coroutine() вернет объект корутины, но не выполнит ее код.

Когда что использовать:

  • def: Для CPU-bound задач (математические вычисления, обработка данных в памяти) и простого последовательного кода.
  • async def: Для I/O-bound задач (сетевые запросы, работа с файлами, базами данных), где программа большую часть времени ожидает ответа от внешних ресурсов.

Пример:

import asyncio
import time

# Синхронная функция (блокирующая)
def sync_task():
    print("Начало синхронной задачи...")
    time.sleep(1) # Блокирует поток на 1 секунду
    print("...синхронная задача завершена")
    return {"data": "sync_data"}

# Асинхронная функция (неблокирующая)
async def async_task():
    print("Начало асинхронной задачи...")
    await asyncio.sleep(1) # Не блокирует, передает управление
    print("...асинхронная задача завершена")
    return {"data": "async_data"}

async def main():
    # Вызов корутины с помощью await
    result = await async_task()
    print(result)

# Для запуска асинхронного кода
# asyncio.run(main())