Принципы работы с async/await в Python: практическое руководство с примерами
Асинхронное программирование в Python с использованием async/await позволяет эффективно выполнять задачи, связанные с операциями ввода-вывода (IO), такие как работа с сетью, файлами или базами данных. В этой статье мы рассмотрим основные принципы работы с async/await на практических примерах, а также изучим ключевые методы модуля asyncio.
Рассмотрим принципы работы с async/await на практических примерах. Для начала рассмотрим базовый пример асинхронной функции, которая имитирует загрузку данных с разных URL:
import asyncio
async def fetch_data(url):
await asyncio.sleep(1)
return f"Данные с {url}"
async def main():
# Параллельное создание задач
task1 = asyncio.create_task(fetch_data("site1.com"))
task2 = asyncio.create_task(fetch_data("site2.com"))
# Ждём результатов обоих задач одновременно
result1, result2 = await asyncio.gather(task1, task2)
print(result1)
print(result2)
# Запуск
# asyncio.run(main())
Теперь рассмотрим
Для лучшего понимания потока выполнения асинхронного кода, рассмотрим рисунок последовательности:
import asyncio
async def fetch_data(url):
await asyncio.sleep(1)
return f"Данные с {url}"
async def main():
# Параллельное создание задач
task1 = asyncio.create_task(fetch_data("site1.com"))
task2 = asyncio.create_task(fetch_data("site2.com"))
# Ждём результатов обоих задач одновременно
result1, result2 = await asyncio.gather(task1, task2)
print(result1)
print(result2)
# Запуск
# asyncio.run(main())

Рассмотрим подробнее, что происходит:
1. Создание задачи
Главная программа создаёт две задачи одновременно, не дожидаясь завершения первой
2. Параллельное выполнение
Обе задачи выполняются независимо друг от друга, каждая ожидает по 1 секунде
3. Обработка результата
После завершения обеих задач их результаты собираются через asyncio.gather()
Для лучшего понимания преимуществ async/await, сравним синхронный и асинхронный подходы:
| Характеристика | Синхронный код | Асинхронный код (async/await) | |
| Выполнение операций | Последовательное, блокирующее | Параллельное, неблокирующее | |
| Использование CPU |
|
Время ожидания используется для других задач | |
| Сложность кода | Простой, линейный | Немного сложнее, но читаемый | |
| Масштабируемость | Ограниченная | Высокая при работе с IO операциями |
Основные преимущества async/await:
- Эффективность:
- Одновременное выполнение нескольких операций
- Оптимальное использование системных ресурсов
- Быстрое выполнение IO-операций
- Читаемость кода:
- Синтаксис близок к обычному синхронному коду
- Логика выполнения более очевидна
- Проще поддерживать и модифицировать
- Масштабируемость:
- Легко добавлять новые асинхронные операции
- Удобно управлять параллельным выполнением
- Простая обработка ошибок через try-except
Для практического применения важно помнить:
- Используйте async/await для IO-операций (сеть, файлы, базы данных)
- Комбинируйте задачи с помощью
asyncio.gather()для параллельного выполнения - Обрабатывайте ошибки в каждой асинхронной функции отдельно
- Не используйте async/await для вычислительных задач без IO операций
Такой подход позволяет создавать эффективные и масштабируемые приложения с минимальными изменениями в структуре кода.
Давайте рассмотрим основные полезные процедуры модуля asyncio и их практическое применение.
Основные методы управления задачами
Рекомендации по использованию
- Логирование:
- Всегда используйте именованные логгеры
- Логируйте ошибки с контекстом
- Используйте разные уровни логирования (INFO, WARNING, ERROR)
- Управление ресурсами:
- Используйте контекстные менеджеры (async with)
- Всегда очищайте ресурсы в блоке finally
- Используйте семафоры для ограничения параллельных операций
- Обработка ошибок:
- Обрабатывайте специфические исключения
- Используйте return_exceptions в gather
- Логируйте ошибки с контекстом
- Таймауты:
- Устанавливайте разумные таймауты для операций
- Обрабатывайте TimeoutError
- Отменяйте задачи при таймауте
- Именование задач:
- Давайте осмысленные имена задачам
- Используйте name параметр в create_task
- Это помогает в отладке и мониторинге
Анти-паттерны, которых следует избегать
Заключение
Асинхронное программирование с использованием async/await позволяет создавать высокопроизводительные и масштабируемые приложения. Правильное использование методов модуля asyncio и соблюдение рекомендаций помогут избежать распространённых ошибок и улучшить качество кода.
Эта статья поможет вам освоить асинхронное программирование в Python и эффективно применять его в своих проектах.
Вступайте в нашу телеграмм-группу Инфостарт
Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».
- 0% комиссии — оплата напрямую исполнителю;
- Исполнители любого масштаба — от отдельных специалистов до команд под проект;
- Прямой обмен контактами между заказчиком и исполнителем;
- Безопасная сделка — при необходимости;
- Рейтинги, кейсы и прозрачная система откликов.