Сообщить об ошибке.

Создание Future и Task методами низкоуровнего API модуля asyncio

В разделе рассмотрены методы низкоуровнего API цикла событий, позволяющие создавать задачи и объекты будущих результатов в асинхронном коде с применением модуля asyncio.

Прежде чем что-то делать с циклом событий, его необходимо создать или получить функциями, описанными в разделе "Создание, запуск и получение цикла событий".

Содержание:


loop.create_future():

Метод loop.create_future() создает объект asyncio.Future, прикрепленный к циклу событий.

Это предпочтительный способ создания объектов Futures в модуле asyncio, что позволяет сторонним циклам событий предоставлять альтернативные реализации объекта Future, с лучшей производительностью или инструментами.

loop.create_task(coro, *, name=None, context=None):

Метод loop.create_task() планирует выполнение сопрограмм coro. Возвращает объект asyncio.Task.

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

Если указан аргумент name, не равный None, то он устанавливается как имя задачи с помощью метода Task.set_name().

Необязательный ключевой аргумент контекста, позволяет указать пользовательский contextvars.Context для запуска сопрограммы. Когда контекст не предоставляется, то создается текущая копия контекста.

Изменено в Python 3.8: Добавлен аргумент name.

Изменено в Python 3.11: Добавлен аргумент context.

loop.set_task_factory(factory):

Метод loop.set_task_factory() устанавливает фабрику задач, которая будет использоваться методом loop.create_task().

Если аргумент factory=None, то будет установлена ​​фабрика задач по умолчанию. В противном случае factory должен быть вызываемым объектом с сигнатурой в виде (loop, coro), где loop - это ссылка на активный цикл событий, а coro - это объект сопрограммы. Вызываемый объект должен возвращать объект, совместимый с asyncio.Future.

loop.get_task_factory():

Метод loop.get_task_factory() возвращает фабрику задач или None, если используется фабрика по умолчанию.

Пример использования создания задач и ожидания результатов в низкоуровневом коде.

В этом примере создается объект Future, так-же создается и планируется асинхронная задача, которая принимает и передает результат для Future. Программа будет ждать, пока объект Future не получит результат:

import asyncio

async def set_after(fut, delay, value):
    # Задержка на `delay` секунд.
    await asyncio.sleep(delay)
    # установка `value` как результат 
    # `fut` объекта Future.
    fut.set_result(value)

async def main():
    # Получим текущий цикл событий.
    loop = asyncio.get_event_loop()
    # Создадим новый объект Future.
    fut = loop.create_future()
    # Запускаем сопрограмму `set_after()` в параллельной задаче.
    # Здесь используется низкоуровневый API `loop.create_task()`, 
    loop.create_task(set_after(fut, 1, '... world'))

    print('hello ...')
    # Ждем, пока `fut` не получит результат 
    # (1 секунда), после печатаем его.
    result = await fut
    print(result)

if __name__ == '__main__':
    asyncio.run(main())