Асинхронное программирование появилось в языке Python начиная с версии 3.5 с введением ключевых слов async и await. Изначально для асинхронных задач использовались такие библиотеки, как asyncio и генераторы на основе корутин, что было сложно для понимания и сопровождения. С появлением синтаксиса async/await асинхронный код стал более явным и читаемым, приближенным к привычному синхронному стилю.
До появления async/await асинхронность реализовывалась через колбэки и генераторы (например, с помощью библиотеки tornado или старых API asyncio). Такой код был сложен для отладки и сопровождения.
Главная проблема при обработке большого числа одновременных I/O операций (сетевые запросы, файловый ввод/вывод) в синхронном коде — блокировка основного потока. Это приводит к снижению производительности и невозможности эффективного использования ресурсов.
Асинхронное программирование с помощью async/await позволяет выполнять множество операций ввода-вывода параллельно в рамках одного потока, избегая блокировок. При этом синтаксис близок к обычным функциям, что облегчает читаемость и отладку.
import asyncio async def fetch_data(delay): print(f"Start fetching after {delay}s delay") await asyncio.sleep(delay) print(f"Done fetching after {delay}s delay") return delay async def main(): results = await asyncio.gather( fetch_data(1), fetch_data(2), fetch_data(3) ) print("Results:", results) asyncio.run(main())
Может ли функция, определенная с помощью async def, быть вызвана как обычная функция?
Нет. Вызов такой функции возвращает объект корутины, который не выполняется до передачи его в event loop (например, с помощью await или asyncio.run()).
def foo(): return 42 async def bar(): return 42 print(foo()) # 42 print(bar()) # <coroutine object bar at ...>
Можно ли использовать await вне асинхронной функции?
Нет. Ключевое слово await должно использоваться только внутри функций, объявленных с помощью async def. Попытка поставить await вне такой функции вызовет SyntaxError.
# Ошибка! await asyncio.sleep(1) # SyntaxError: 'await' outside async function
Работает ли асинхронность для операций, не связанных с I/O (например, вычисления)?
Нет. Асинхронность эффективна только для операций ввода-вывода. Для вычислительных задач по-прежнему нужен multiprocessing или threading, иначе будет блокироваться event loop.
Плюсы:
Минусы:
Негативный кейс: Молодые разработчики решили ускорить приложение с помощью async/await, но асинхронно делали только вычисления, а не сетевые запросы. Приложение не ускорилось. Плюсы: познакомились с синтаксисом. Минусы: прибыли нет, код усложнился.
Положительный кейс: Асинхронно обрабатывали тысячи запросов к API. Сервер стал обслуживать больше клиентов без увеличения ресурсов. Плюсы: существенно выросла производительность, архитектура стала проще. Минусы: вырос порог вхождения для новичков.