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

Что такое асинхронная функция в Python?

1.0 Junior🔥 151 комментариев
#Python Core#Асинхронность и многопоточность

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

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

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

Что такое асинхронная функция в Python?

Асинхронная функция (async function) в Python — это функция, которая может быть приостановлена и возобновлена, позволяя другим кодам выполняться пока она ожидает (например, ответ от API или доступ к БД). Асинхронное программирование позволяет обрабатывать множество операций одновременно в одном потоке, значительно повышая производительность приложений с I/O операциями.

Основные концепции

1. Синхронный vs Асинхронный код

import time
import asyncio

# СИНХРОННЫЙ КОД (блокирующий)
def fetch_user(user_id):
    """Этот код заблокирует, пока ждет ответа"""
    time.sleep(2)  # Имитация сетевого запроса
    print(f"Получили пользователя {user_id}")
    return {"id": user_id, "name": "Иван"}

print("Начало")
for i in range(3):
    fetch_user(i)
print("Конец")
# Выполняется последовательно: 6 секунд (2+2+2)

# АСИНХРОННЫЙ КОД (неблокирующий)
async def fetch_user_async(user_id):
    """Эта функция может быть приостановлена"""
    await asyncio.sleep(2)  # Имитация сетевого запроса
    print(f"Получили пользователя {user_id}")
    return {"id": user_id, "name": "Иван"}

async def main():
    print("Начало")
    tasks = [fetch_user_async(i) for i in range(3)]
    results = await asyncio.gather(*tasks)  # Все выполняются параллельно
    print("Конец")

asyncio.run(main())
# Выполняется параллельно: ~2 секунды (все трое одновременно)

Синтаксис асинхронных функций

1. Определение асинхронной функции

import asyncio

# Обычная функция
def sync_function():
    return "Результат"

# Асинхронная функция
async def async_function():
    return "Результат"

# Асинхронная функция с ожиданием
async def async_with_await():
    result = await async_function()
    return result

2. Использование await

await используется только внутри асинхронной функции для ожидания выполнения другой асинхронной функции:

async def fetch_user(user_id):
    # await приостанавливает выполнение функции
    user_data = await get_user_from_api(user_id)
    posts = await get_user_posts(user_id)
    return {"user": user_data, "posts": posts}

async def get_user_from_api(user_id):
    await asyncio.sleep(1)
    return {"id": user_id, "name": "Иван"}

async def get_user_posts(user_id):
    await asyncio.sleep(1)
    return ["Пост 1", "Пост 2"]

3. Запуск асинхронного кода

# Способ 1: asyncio.run() (Python 3.7+, рекомендуется)
async def main():
    result = await async_function()
    return result

result = asyncio.run(main())

# Способ 2: используя event loop напрямую (старый способ)
loop = asyncio.get_event_loop()
result = loop.run_until_complete(main())

Практические примеры

1. Параллельные HTTP запросы

import asyncio
import aiohttp

async def fetch_user_data(session, user_id):
    """Получить данные одного пользователя"""
    url = f"https://api.example.com/users/{user_id}"
    async with session.get(url) as response:
        return await response.json()

async def fetch_all_users(user_ids):
    """Получить данные всех пользователей параллельно"""
    async with aiohttp.ClientSession() as session:
        tasks = [fetch_user_data(session, uid) for uid in user_ids]
        results = await asyncio.gather(*tasks)
    return results

# Использование
user_ids = [1, 2, 3, 4, 5]
results = asyncio.run(fetch_all_users(user_ids))
# Вместо 5 последовательных запросов (5 секунд),
# они выполняются параллельно (~1 секунда)

2. Асинхронная работа с базой данных

import asyncio
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine

async def get_user_from_db(session: AsyncSession, user_id: int):
    """Получить пользователя из БД асинхронно"""
    result = await session.execute(
        select(User).where(User.id == user_id)
    )
    return result.scalar_one_or_none()

async def get_multiple_users(session: AsyncSession, user_ids: list):
    """Получить нескольких пользователей параллельно"""
    tasks = [get_user_from_db(session, uid) for uid in user_ids]
    users = await asyncio.gather(*tasks)
    return users

3. Таймауты и обработка ошибок

async def fetch_with_timeout(url, timeout=5):
    """Получить данные с таймаутом"""
    try:
        async with asyncio.timeout(timeout):
            async with aiohttp.ClientSession() as session:
                async with session.get(url) as response:
                    return await response.json()
    except asyncio.TimeoutError:
        print(f"Таймаут при запросе к {url}")
        return None
    except aiohttp.ClientError as e:
        print(f"Ошибка сети: {e}")
        return None

# Использование
data = asyncio.run(fetch_with_timeout("https://api.example.com/data"))

4. asyncio.gather и asyncio.create_task

async def main():
    # Способ 1: asyncio.gather (рекомендуется для множественных задач)
    results = await asyncio.gather(
        fetch_user(1),
        fetch_user(2),
        fetch_user(3),
        return_exceptions=True  # Не прерывать при ошибках
    )
    
    # Способ 2: asyncio.create_task (для долгоживущих задач)
    task1 = asyncio.create_task(fetch_user(1))
    task2 = asyncio.create_task(fetch_user(2))
    
    result1 = await task1
    result2 = await task2
    
    # Способ 3: задачи можно отменить
    task = asyncio.create_task(long_running_task())
    await asyncio.sleep(5)
    task.cancel()  # Отменить задачу

5. Асинхронный контекстный менеджер

class AsyncDatabaseConnection:
    async def __aenter__(self):
        """Подключение к БД"""
        self.connection = await connect_to_db()
        return self.connection
    
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """Закрытие соединения"""
        await self.connection.close()

# Использование
async def main():
    async with AsyncDatabaseConnection() as db:
        users = await db.query("SELECT * FROM users")
        return users

FastAPI с асинхронностью

from fastapi import FastAPI
import asyncio

app = FastAPI()

@app.get("/users/{user_id}")
async def get_user(user_id: int):
    """Асинхронный endpoint"""
    # Может обрабатывать многих пользователей одновременно
    user = await fetch_user_from_db(user_id)
    posts = await fetch_user_posts(user_id)
    return {"user": user, "posts": posts}

@app.get("/users")
async def get_multiple_users(ids: list[int]):
    """Параллельная загрузка нескольких пользователей"""
    users = await asyncio.gather(*[fetch_user_from_db(uid) for uid in ids])
    return users

# Этот сервер может обслуживать тысячи одновременных запросов
# потому что он не блокируется на I/O операциях

Когда использовать асинхронность

# ✅ ИСПОЛЬЗУЙ асинхронность для:
# - HTTP запросов (requests, aiohttp)
# - Работы с БД (asyncpg, motor)
# - Файловой системы (aiofiles)
# - Web приложений (FastAPI, aiohttp)
# - Реального времени (WebSocket)

# ❌ НЕ используй асинхронность для:
# - Чистых вычислений (используй multiprocessing)
# - I/O блокирующихся операций (используй threading или multiprocessing)
# - Когда нет I/O операций вообще

Мониторинг асинхронного кода

import asyncio
import time

async def timed_task(name, delay):
    start = time.time()
    await asyncio.sleep(delay)
    elapsed = time.time() - start
    print(f"{name} завершена за {elapsed:.2f}с")
    return name

async def main():
    start_total = time.time()
    
    results = await asyncio.gather(
        timed_task("Задача 1", 2),
        timed_task("Задача 2", 3),
        timed_task("Задача 3", 1),
    )
    
    total_time = time.time() - start_total
    print(f"Общее время: {total_time:.2f}с (параллельное выполнение)")

asyncio.run(main())
# Результат: ~3 секунды вместо 6 (если бы выполнялось последовательно)

Заключение

Асинхронное программирование в Python критически важно для:

  • Высокопроизводительных веб-приложений
  • Приложений, работающих с внешними API
  • Приложений, обслуживающих многих пользователей одновременно

Основное правило: используй async/await для I/O операций, которые могут быть приостановлены. Это позволяет твоему коду обрабатывать множество одновременных операций эффективно.

Что такое асинхронная функция в Python? | PrepBro