Документация Python неофициальный перевод
Содержание страницы

FutureFutures

Future-объекты используются для связи низкоуровневого кода на основе колбэков с высокоуровневым кодом async/await.

Функции FutureFuture Functions

asyncio.isfuture(obj)

Возвращает True, если obj – это:

  • экземпляр asyncio.Future,

  • экземпляр asyncio.Task,

  • Future-подобный объект с атрибутом _asyncio_future_blocking.

Новое в версии 3.5.

asyncio.ensure_future(obj, *, loop=None)

Возвращает:

  • obj как есть, если objFuture, Task или Future-подобный объект (проверка выполняется с помощью isfuture()).

  • объект Task, оборачивающий obj, если obj – корутина (проверка выполняется с помощью iscoroutine()); в этом случае корутина будет запланирована через ensure_future().

  • объект Task, который будет ожидать obj, если obj является ожидаемым объектом (проверка выполняется с помощью inspect.isawaitable()).

Если obj не является ни одним из вышеперечисленных, возбуждается TypeError.

Важно

См. также функцию create_task(), которая является предпочтительным способом создания новых задач.

Изменено в версии 3.5.1: Функция принимает любой ожидаемый объект.

asyncio.wrap_future(future, *, loop=None)

Оборачивает объект concurrent.futures.Future в объект asyncio.Future.

Объект FutureFuture Object

class asyncio.Future(*, loop=None)

Future представляет собой окончательный результат асинхронной операции. Не потокобезопасен.

Future – это ожидаемый объект. Корутины могут ожидать объекты Future, пока у них не будет установлен результат или исключение или пока они не будут отменены.

Обычно Futures используются для того, чтобы низкоуровневый код на основе колбэков (например, в протоколах, реализованных с помощью asyncio транспорты) мог взаимодействовать с высокоуровневым кодом async/await.

Эмпирическое правило: никогда не предоставлять объекты Future в пользовательских API, а рекомендуемый способ создания объекта Future – вызвать loop.create_future(). Таким образом, альтернативные реализации цикла событий могут внедрять свои собственные оптимизированные реализации объекта Future.

Изменено в версии 3.7: Добавлена поддержка модуля contextvars.

result()

Возвращает результат объекта Future.

Если Future находится в состоянии done и имеет результат, установленный методом set_result(), возвращается значение результата.

Если Future находится в состоянии done и имеет исключение, установленное методом set_exception(), этот метод возбуждает это исключение.

Если Future был отменён, этот метод возбуждает исключение CancelledError.

Если результат Future ещё недоступен, этот метод вызывает исключение InvalidStateError.

set_result(result)

Помечает Future как done и устанавливает его результат.

Вызывает ошибку InvalidStateError, если Future уже завершён.

set_exception(exception)

Помечает Future как done и устанавливает исключение.

Вызывает ошибку InvalidStateError, если Future уже завершён.

done()

Возвращает True, если Future находится в состоянии done.

Future находится в состоянии done, если оно было отменено или если у него есть результат или исключение, установленные вызовами set_result() или set_exception().

cancelled()

Возвращает True, если Future был отменён.

Этот метод обычно используется для проверки того, не был ли Future отменён, перед установкой результата или исключения:

if not fut.cancelled():
    fut.set_result(42)
add_done_callback(callback, *, context=None)

Добавляет колбэк, который будет выполнен, когда Future перейдёт в состояние done.

Колбэк вызывается с объектом Future в качестве единственного аргумента.

Если Future уже находится в состоянии done на момент вызова этого метода, колбэк планируется с помощью loop.call_soon().

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

functools.partial() можно использовать для передачи параметров колбэку, например:

# Вызвать 'print("Future:", fut)', когда "fut" будет завершён.
fut.add_done_callback(
    functools.partial(print, "Future:"))

Изменено в версии 3.7: Добавлен параметр context (только ключевой). Подробнее см. PEP 567.

remove_done_callback(callback)

Удаляет колбэк из списка колбэков.

Возвращает количество удалённых колбэков – обычно 1, если только колбэк не был добавлен более одного раза.

cancel()

Отменяет Future и планирует выполнение колбэков.

Если Future уже завершён или отменён, вернуть False. Иначе перевести Future в состояние отменён, запланировать колбэки и вернуть True.

exception()

Возвращает исключение, которое было установлено для этого Future.

Исключение (или None, если исключение не было установлено) возвращается только если Future завершён.

Если Future был отменён, этот метод возбуждает исключение CancelledError.

Если Future ещё не завершён, этот метод возбуждает исключение InvalidStateError.

get_loop()

Возвращает цикл событий, к которому привязан объект Future.

Добавлено в версии 3.7.

В этом примере создаётся объект Future, создаётся и планируется асинхронная задача для установки результата Future, и выполняется ожидание, пока Future не получит результат:

async def set_after(fut, delay, value):
    # Приостановиться на *delay* секунд.
    await asyncio.sleep(delay)

    # Установить *value* в качестве результата Future *fut*.
    fut.set_result(value)

async def main():
    # Получить текущий цикл событий.
    loop = asyncio.get_running_loop()

    # Создать новый объект Future.
    fut = loop.create_future()

    # Запустить корутину "set_after()" в параллельной задаче.
    # Мы используем низкоуровневый API "loop.create_task()", поскольку
    # у нас уже есть ссылка на цикл событий.
    # В противном случае можно было бы просто использовать "asyncio.create_task()".
    loop.create_task(
        set_after(fut, 1, '... world'))

    print('hello ...')

    # Ожидать, пока у *fut* не появится результат (1 секунда), и вывести его.
    print(await fut)

asyncio.run(main())

Важно

Объект Future был спроектирован так, чтобы имитировать concurrent.futures.Future. Ключевые отличия включают: