Какие типы awaitable-объектов существуют в Python asyncio?

Ответ

awaitable-объект в asyncio — это любой объект, который можно использовать в выражении await. Существует три основных типа:

  1. Корутина (Coroutine) Это результат вызова асинхронной функции, определенной через async def. Сама по себе корутина ничего не выполняет, пока ее не запустят с помощью await или не обернут в Task.

    import asyncio
    
    async def my_coroutine():
        print("Coroutine is running")
        return 42
    
    # my_coroutine() создает объект корутины, но не выполняет код внутри
    coro = my_coroutine()
    # await запускает выполнение
    result = await coro
  2. Задача (Task) Это объект, который планирует выполнение корутины в цикле событий asyncio. Задачи позволяют запускать корутины конкурентно (параллельно). Создаются с помощью asyncio.create_task().

    task = asyncio.create_task(my_coroutine())
    # Можно выполнять другие действия, пока task работает в фоне
    await task
  3. Объект Future Низкоуровневый awaitable-объект, представляющий конечный результат асинхронной операции. Обычно используется не в прикладном коде, а разработчиками библиотек для управления состоянием операций (ожидание, завершение, ошибка).

Ключевое различие: корутины — это "рецепты" асинхронных операций, а Task — это то, что запускает их выполнение в цикле событий.

Ответ 18+ 🔞

Слушай, а вот этот твой awaitable в asyncio — это, блядь, как такая универсальная хуйня, которую можно воткнуть после слова await. Их там, этих ублюдков, всего три вида, и сейчас я тебе их разложу, как божий одуванчик.

Первое — это корутина (Coroutine). Это когда ты написал async def, вызвал эту функцию, а она тебе, сука, не выполняется сразу, а просто плюёт в рожу каким-то объектом. Он лежит и ждёт, пока его не разбудят словом await. Сам по себе он нихуя не делает, просто нагло дышит.

import asyncio

async def my_coroutine():
    print("Coroutine is running")
    return 42

# Смотри, вот она, сука, родилась — корутина!
coro = my_coroutine()
# А вот тут её уже будят и заставляют работать
result = await coro

Второе — задача (Task). Это уже посерьёзнее. Это когда ты берёшь корутину и суёшь её в asyncio.create_task(). Цикл событий её хватает и начинает гонять в фоне, параллельно с другим говном. Это уже не просто рецепт, а уже готовящееся блюдо, за которым можно следить.

task = asyncio.create_task(my_coroutine())
# Пока эта задачка там копошится, ты можешь другую хуйню делать
await task

И третье, на самый крайний случай — Future. Это, блядь, такой низкоуровневый уродец, который представляет собой просто обещание, что когда-нибудь будет результат. Обычные смертные с ним не работают, это для библиотечных шаманов, которые колдуют над состоянием операций — ждёт, выполнилось или накрылось медным тазом.

Короче, суть в чём: корутина — это как идея, а Task — это уже процесс её реализации, который бегает по циклу событий и всем мешает. Вот и вся магия, ёпта.