Ответ
async и await — это синтаксические конструкции в Python, предназначенные для написания асинхронного, неблокирующего кода. Они позволяют эффективно управлять операциями ввода-вывода (I/O), такими как сетевые запросы или работа с базой данных, не замораживая выполнение всей программы.
async def: Объявляет функцию как корутину (coroutine). Это особый тип функции, выполнение которой можно приостановить и возобновить.await: Приостанавливает выполнение корутины и передает управление обратно в цикл событий (event loop). Код продолжит выполняться только после завершения ожидаемой операции (например, получения ответа от сервера).
Ключевая идея: Пока одна корутина ждет завершения I/O-операции с помощью await, цикл событий может запустить или продолжить выполнение других задач, что значительно повышает производительность I/O-bound приложений.
Пример с asyncio:
import asyncio
import time
async def fetch_data(delay):
print("Начало загрузки данных...")
# Имитация долгой сетевой операции
await asyncio.sleep(delay)
print(f"Данные загружены за {delay} сек.")
return {"data": f"some_data_from_{delay}s_request"}
async def main():
start_time = time.time()
# Запускаем обе корутины конкурентно, не дожидаясь завершения каждой по очереди
task1 = asyncio.create_task(fetch_data(2))
task2 = asyncio.create_task(fetch_data(3))
# Ожидаем завершения обеих задач
result1 = await task1
result2 = await task2
end_time = time.time()
print(f"Все операции завершены за {end_time - start_time:.2f} сек.")
# Запуск главной асинхронной функции
asyncio.run(main())
# Вывод будет примерно таким:
# Начало загрузки данных...
# Начало загрузки данных...
# Данные загружены за 2 сек.
# Данные загружены за 3 сек.
# Все операции завершены за 3.01 сек. (а не за 2+3=5 сек)
Важно: await можно использовать только внутри функции, объявленной с помощью async def.
Ответ 18+ 🔞
Давай разберёмся с этими async и await, а то народ, бывает, нихуя не понимает, а потом в коде пиздец творится.
Вот представь, ты стоишь в очереди за пивом, а там один мудак такой долго копается, карточку ищет. Все за ним ждут, и вся очередь простаивает, блядь. Это синхронный код — пока одна операция не закончится, дальше нихуя не двигается.
А теперь асинхронность — это как будто ты подошёл к бармену, заказал пиво, а он тебе: «Жди, пока нальют». И вместо того чтобы тупо стоять и пялиться в потолок, ты пошёл на хуй, чипсы взял, с тёлкой поболтал, потом вернулся — а пиво уже готово. И очередь вся не стоит, а делает свои дела. Вот это и есть асинхронность, ёпта!
async def— это не просто функция, это корутина, такая хитрая жопа, которую можно поставить на паузу, а потом обратно запустить. Объявляешь её — и всё, функция теперь может «засыпать» и «просыпаться».await— это и есть команда «спать». Говоришьawait какая_то_долгая_хрень()— и всё, выполнение корутины останавливается, но программа-то не встаёт! Цикл событий (event loop) — этот главный распиздяй — идёт проверять, а нет ли других корутин, которым уже пора проснуться? И так по кругу, пока твоя операция не сделается.
Суть в чём: пока одна корутина ждёт ответа от сервера или чтения файла, другие не тупят, а работают. Для задач, где много ожидания (сеть, базы данных), это овердохуища быстрее.
Смотри, как это выглядит в деле:
import asyncio
import time
async def fetch_data(delay):
print("Начало загрузки данных...")
# Представь, что тут запрос в интернет, а не просто сон
await asyncio.sleep(delay)
print(f"Данные загружены за {delay} сек.")
return {"data": f"some_data_from_{delay}s_request"}
async def main():
start_time = time.time()
# Создаём задачи — это как отправить двух курьеров одновременно
task1 = asyncio.create_task(fetch_data(2))
task2 = asyncio.create_task(fetch_data(3))
# Ждём, пока оба курьера вернутся, но они же едут параллельно!
result1 = await task1
result2 = await task2
end_time = time.time()
print(f"Все операции завершены за {end_time - start_time:.2f} сек.")
# Запускаем всю эту карусель
asyncio.run(main())
# Вывод будет примерно таким:
# Начало загрузки данных...
# Начало загрузки данных...
# Данные загружены за 2 сек.
# Данные загружены за 3 сек.
# Все операции завершены за 3.01 сек. (а не за 2+3=5 сек, вот это магия, блядь!)
Видишь? Вторая задача заняла 3 секунды, но мы не ждали её завершения, чтобы начать первую. Они стартанули вместе, и общее время — это время самой долгой задачи, а не сумма. Красота, в рот меня чих-пых!
И запомни, ёпта: await можно юзать только внутри async def. Вылезешь с ним в обычную функцию — получишь ошибку, и будешь сидеть, чесать репу, как тот Герасим из рассказа, который только «Муму» сказать мог. Не будь как Герасим.