Deprecated: Creation of dynamic property Yoast\Presenters\CommonArticlePresenter::$metaPropertyType is deprecated in /var/www/html/web/app/themes/tutortop-blog/Yoast/Presenters/CommonArticlePresenter.php on line 26

Deprecated: Creation of dynamic property Yoast\Presenters\CommonArticlePresenter::$metaPropertyType is deprecated in /var/www/html/web/app/themes/tutortop-blog/Yoast/Presenters/CommonArticlePresenter.php on line 26

Deprecated: Creation of dynamic property Yoast\Presenters\CommonArticlePresenter::$metaPropertyType is deprecated in /var/www/html/web/app/themes/tutortop-blog/Yoast/Presenters/CommonArticlePresenter.php on line 26
Async Python: asyncio, корутины, производительность - полное руководство
25.06.2025
192
7 мин

Асинхронность в Python: от теории к практическому применению

Что такое асинхронность и зачем она нужна

Представьте ресторан, где повар готовит блюда строго по очереди: начал варить суп — ждет 30 минут, пока он сварится, не делая ничего другого. Затем начинает жарить мясо. Это синхронный подход.

Асинхронность — это когда повар ставит суп вариться, а пока он готовится, жарит мясо, нарезает салат и делает другие дела. Когда суп готов — он получает сигнал и переключается на него.

В Python асинхронность особенно эффективна для I/O-bound операций: сетевых запросов, работы с файлами, базами данных. Например, при обработке 1000 HTTP-запросов синхронный код может выполняться 10-15 секунд, а асинхронный — 1-2 секунды. Рассмотрим асинхронность подробно, а об остальных интересных особенностях разработки вы сможете узнать на онлайн-курсах по Python.

Основные концепции асинхронного программирования

Событийный цикл (Event Loop)

Event Loop — это сердце асинхронности. Он управляет выполнением корутин, переключаясь между ними, когда одна ждет завершения операции.

import asyncio

async def main():
print("Начинаем работу")
await asyncio.sleep(1)
print("Работа завершена")

# Запуск событийного цикла
asyncio.run(main())

Корутины и async/await

Корутина — это специальная функция, которая может приостановить свое выполнение и передать управление другим функциям. Определяется с помощью async def, вызывается с await.

async def fetch_data(url):
print(f"Начинаем загрузку {url}")
await asyncio.sleep(2) # имитация сетевого запроса
print(f"Данные с {url} загружены")
return f"Данные с {url}"

async def main():
# Последовательное выполнение
data1 = await fetch_data("https://api1.com")
data2 = await fetch_data("https://api2.com")

# Параллельное выполнение
task1 = asyncio.create_task(fetch_data("https://api3.com"))
task2 = asyncio.create_task(fetch_data("https://api4.com"))

results = await asyncio.gather(task1, task2)
print(results)

Практические примеры использования

Пример 1: Асинхронные HTTP-запросы

Один из самых частых случаев применения — обработка множественных HTTP-запросов:

import aiohttp
import asyncio
import time

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

async def fetch_multiple_urls(urls):
async with aiohttp.ClientSession() as session:
tasks = [fetch_url(session, url) for url in urls]
results = await asyncio.gather(*tasks)
return results

# Сравнение производительности
urls = ["https://httpbin.org/delay/1"] * 10

# Асинхронный подход
start = time.time()
results = asyncio.run(fetch_multiple_urls(urls))
async_time = time.time() - start
print(f"Асинхронно: {async_time:.2f} секунд")

Пример 2: Асинхронная работа с базой данных

import asyncpg
import asyncio

async def get_user_data(user_ids):
conn = await asyncpg.connect('postgresql://user:pass@localhost/db')

try:
# Асинхронные запросы к БД
tasks = []
for user_id in user_ids:
query = "SELECT * FROM users WHERE id = $1"
task = conn.fetchrow(query, user_id)
tasks.append(task)

results = await asyncio.gather(*tasks)
return results
finally:
await conn.close()

Сравнение подходов к конкурентности

ПодходПотребление памятиПроизводительность I/OСложность кодаCPU-bound задачи
СинхронныйНизкоеМедленнаяПростаяПодходит
МногопоточностьВысокоеСредняяСложнаяОграничено GIL
АсинхронностьНизкоеВысокаяСредняяНе подходит
МультипроцессингОчень высокоеНизкаяОчень сложнаяОтлично

Зарплаты Python-разработчиков по уровню владения асинхронностью

Без знания async
90,000 ₽
Базовые знания
130,000 ₽
Продвинутый уровень
170,000 ₽
Эксперт + архитектура
200,000 ₽

Продвинутые концепции

Асинхронные менеджеры контекста

Для управления ресурсами в асинхронном коде используются асинхронные менеджеры контекста:

class AsyncDatabaseConnection:
async def __aenter__(self):
self.connection = await asyncpg.connect(DATABASE_URL)
return self.connection

async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.connection.close()

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

Обработка ошибок и таймауты

Важный аспект работы с асинхронным кодом — правильная обработка ошибок:

async def robust_fetch(url, timeout=5):
try:
async with asyncio.timeout(timeout):
async with aiohttp.ClientSession() as session:
async with session.get(url) as response:
if response.status == 200:
return await response.json()
else:
raise aiohttp.ClientResponseError()
except asyncio.TimeoutError:
print(f"Таймаут при запросе к {url}")
return None
except aiohttp.ClientError as e:
print(f"Ошибка сети: {e}")
return None
Мужчина изучает асинхронность в Python

Частые ошибки и как их избежать

По данным анализа GitHub проектов, 43% ошибок в асинхронном коде связаны с неправильным использованием await. Вот основные проблемы:

  • Забытый await: Вызов корутины без await приводит к предупреждению
  • Блокирующие операции: Использование requests вместо aiohttp
  • Неправильная работа с исключениями: Не перехваченные ошибки в задачах

Как пояснил Юрий Селиванов, создатель asyncio: «Асинхронность — это не серебряная пуля. Она решает конкретные задачи и требует понимания того, когда её применять».

Инструменты и библиотеки

Современная экосистема Python предлагает множество инструментов для асинхронной разработки:

  • aiohttp: HTTP клиент/сервер
  • asyncpg: PostgreSQL драйвер
  • motor: MongoDB драйвер
  • FastAPI: Веб-framework с нативной поддержкой async
  • uvloop: Более быстрая реализация event loop

Тестирование асинхронного кода

Для тестирования асинхронного кода используйте pytest-asyncio:

import pytest

@pytest.mark.asyncio
async def test_async_function():
result = await my_async_function()
assert result == expected_value

# Фикстуры для асинхронных тестов
@pytest.fixture
async def async_client():
async with aiohttp.ClientSession() as session:
yield session

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

Когда использовать асинхронность, а когда многопоточность?

Асинхронность идеальна для I/O-bound операций (сетевые запросы, файлы, БД), где большую часть времени программа ожидает ответа. Многопоточность лучше для CPU-bound задач, но в Python ограничена GIL. Для тяжелых вычислений используйте multiprocessing.

Можно ли смешивать синхронный и асинхронный код?

Да, но осторожно. Синхронный код можно запускать в executor: await loop.run_in_executor(None, sync_function). Асинхронный код из синхронного запускается через asyncio.run() или asyncio.create_task().

Почему мой асинхронный код работает медленно?

Частые причины: блокирующие операции без await, неэффективное использование gather/create_task, отсутствие connection pooling для БД, синхронные библиотеки вместо асинхронных аналогов.

Практический план освоения асинхронности

Пошаговый roadmap для изучения:

  1. Основы (1-2 недели): Изучите async/await, создание простых корутин, asyncio.run()
  2. Практика (2-3 недели): Реализуйте проект с HTTP-запросами, используя aiohttp
  3. Углубление (3-4 недели): Освойте работу с БД через asyncpg/motor, изучите FastAPI
  4. Оптимизация (1-2 недели): Профилирование, connection pooling, обработка ошибок
  5. Архитектура (ongoing): Паттерны проектирования для асинхронных систем

Ключевые навыки для освоения:

  • Понимание event loop и его работы
  • Умение выбирать между concurrency подходами
  • Навыки отладки и профилирования async кода
  • Знание экосистемы асинхронных библиотек

Асинхронность становится стандартом в современной разработке, особенно с ростом микросервисной архитектуры и потребности в высокопроизводительных API.

Оцените статью

4.5 5 (19 оценок)
Хочу стать Python-разработчиком!
Специально для вас мы собрали отдельную подборку лучших онлайн-курсов по Python на рынке и сравнили их по цене, продолжительности и отзывам студентов.
Все курсы по Python-разработке