← Назад к вопросам

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

1.7 Middle🔥 181 комментариев
#Python Core#Асинхронность и многопоточность

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Разница между async def и def

def — синхронные функции

def — это обычные синхронные функции, которые выполняются блокирующим образом. Когда функция вызывается, она:

  1. Запускается на исполнение
  2. Выполняется полностью от начала до конца
  3. Блокирует исполнение остального кода, пока она работает
  4. Возвращает результат через return
import time

def fetch_data():
    """Синхронная функция — блокирует исполнение"""
    time.sleep(2)  # Имитация сетевого запроса
    return "Данные загружены"

def main():
    print("Начало")
    result = fetch_data()  # Программа замерзнет на 2 секунды
    print(result)
    print("Конец")

main()
# Вывод:
# Начало
# (ждём 2 сек)
# Данные загружены
# Конец

async def — асинхронные функции

async def — это асинхронные функции, которые выполняются неблокирующим образом. Они:

  1. Не блокируют исполнение кода
  2. Могут быть приостановлены с помощью await
  3. Позволяют выполнять множество операций одновременно
  4. Требуют event loop для запуска
  5. Возвращают объект корутину, а не сам результат
import asyncio

async def fetch_data():
    """Асинхронная функция — не блокирует исполнение"""
    await asyncio.sleep(2)  # Имитация async операции
    return "Данные загружены"

async def main():
    print("Начало")
    result = await fetch_data()  # Ждём результат, но не блокируем
    print(result)
    print("Конец")

asyncio.run(main())
# Вывод:
# Начало
# (ждём 2 сек, но без блокировки)
# Данные загружены
# Конец

Ключевые различия

Характеристикаdefasync def
ТипОбычная функцияКорутина
Вызовfunc()func() возвращает объект, нужен await
БлокировкаБлокирует выполнениеНе блокирует
ВыполнениеСинхронно, по порядкуАсинхронно в event loop
Ожиданиеtime.sleep()await asyncio.sleep()
ЗапускСразу при вызовеЧерез asyncio.run()
ПараллелизмНетДа (псевдопараллелизм)

Практический пример: одновременное выполнение

Синхронное выполнение (медленно):

import time
import requests

def fetch_url(url):
    response = requests.get(url)
    return len(response.text)

def main():
    urls = [
        'https://httpbin.org/delay/2',
        'https://httpbin.org/delay/2',
        'https://httpbin.org/delay/2',
    ]
    
    start = time.time()
    for url in urls:
        fetch_url(url)
    print(f"Время: {time.time() - start:.1f} сек")  # ~6 секунд

main()

Асинхронное выполнение (быстро):

import asyncio
import aiohttp

async def fetch_url(session, url):
    async with session.get(url) as response:
        return len(await response.text())

async def main():
    urls = [
        'https://httpbin.org/delay/2',
        'https://httpbin.org/delay/2',
        'https://httpbin.org/delay/2',
    ]
    
    start = asyncio.get_event_loop().time()
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_url(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
    print(f"Время: {asyncio.get_event_loop().time() - start:.1f} сек")  # ~2 сек

asyncio.run(main())

async/await синтаксис

await используется для ожидания результата async функции:

async def get_user(user_id):
    # Имитация БД запроса
    await asyncio.sleep(1)
    return {"id": user_id, "name": "Иван"}

async def get_posts(user_id):
    # Имитация API запроса
    await asyncio.sleep(1)
    return ["пост1", "пост2"]

async def main():
    user = await get_user(1)  # Ждём результат
    posts = await get_posts(user['id'])  # Ждём результат
    print(f"Пользователь: {user}")
    print(f"Посты: {posts}")

asyncio.run(main())

asyncio.gather для параллельного выполнения

async def task(name, delay):
    await asyncio.sleep(delay)
    return f"Задача {name} завершена"

async def main():
    # Запуск всех задач одновременно
    results = await asyncio.gather(
        task("A", 2),
        task("B", 1),
        task("C", 3),
    )
    
    for result in results:
        print(result)
    # Результат появится через ~3 сек, а не 6

asyncio.run(main())

Когда использовать async def

Используй async def когда:

  • Множество I/O операций (сетевые запросы, файлы, БД)
  • Нужен высокий throughput (много одновременных операций)
  • Работаешь с asyncio, aiohttp, FastAPI, Telegram Bot (aiogram)

Используй обычный def когда:

  • Чистые вычисления (CPU bound)
  • Нет I/O операций
  • Простой скрипт без необходимости параллелизма

Правило для Telegram Bot (aiogram)

from aiogram import Router
from aiogram.types import Message

router = Router()

# В aiogram ВСЕГДА используй async def для handlers
@router.message()
async def message_handler(message: Message):
    # Даже если функция простая, она должна быть async
    # потому что может понадобиться await для БД запросов
    await message.answer("Привет!")

Вывод

  • def — синхронные, блокирующие функции
  • async def — асинхронные, неблокирующие функции
  • async def позволяет одновременно выполнять множество I/O операций
  • await используется для ожидания результата async функции
  • asyncio.run() или event loop требуются для запуска async кода
В чем разница между async def и def? | PrepBro