Будущее

Исходный код: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py


Объекты Future используются для соединения низкоуровневого кода, основанного на обратном вызове, с высокоуровневым асинхронным/ожидающим кодом.

Будущие функции

asyncio.isfuture(obj)

Возвращает True, если obj является одним из:

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

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

  • объект, похожий на будущее, с атрибутом _asyncio_future_blocking.

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

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

Возвращать:

  • аргумент obj как есть, если obj является Future, Task или объектом, подобным будущему (для теста используется:func:isfuture).

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

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

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

Важно

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

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

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

Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если obj не является объектом, похожим на будущее, а loop не указан и нет запущенного цикла обработки событий.

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

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

Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если future не является объектом, подобным будущему, а loop не указан и нет запущенного цикла обработки событий.

Будущий объект

class asyncio.Future(*, loop=None)

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

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

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

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

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

Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если loop не указан и нет запущенного цикла обработки событий.

result()

Верните результат в будущем.

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

Если будущее выполнено и имеет исключение, установленное методом set_exception(), этот метод вызывает исключение.

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

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

set_result(result)

Отметьте будущее как «готово» и задайте его результат.

Выдает ошибку InvalidStateError, если будущее уже выполнено.

set_exception(exception)

Отметьте будущее как «готово» и установите исключение.

Выдает ошибку InvalidStateError, если будущее уже выполнено.

done()

Верните True, если будущее завершено.

Будущее считается выполненным, если оно было отменено, или если оно имеет результат или исключение, установленное с помощью вызовов set_result() или set_exception().

cancelled()

Верните True, если будущее было отменено.

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

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

Добавьте обратный вызов, который будет запущен, когда будущее будет * завершено*.

Обратный вызов вызывается с использованием объекта Future в качестве единственного аргумента.

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

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

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

# Call 'print("Future:", fut)' when "fut" is done.
fut.add_done_callback(
    functools.partial(print, "Future:"))

Изменено в версии 3.7: Был добавлен параметр context, предназначенный только для ключевых слов. Более подробную информацию смотрите в разделе PEP 567.

remove_done_callback(callback)

Удалите обратный вызов из списка обратных вызовов.

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

cancel(msg=None)

Отмените будущие вызовы и запланируйте обратные.

Если будущее уже выполнено или отменено, верните False. В противном случае измените состояние будущего на отменено, запланируйте обратные вызовы и верните True.

Изменено в версии 3.9: Добавлен параметр msg.

exception()

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

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

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

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

get_loop()

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

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

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

async def set_after(fut, delay, value):
    # Sleep for *delay* seconds.
    await asyncio.sleep(delay)

    # Set *value* as a result of *fut* Future.
    fut.set_result(value)

async def main():
    # Get the current event loop.
    loop = asyncio.get_running_loop()

    # Create a new Future object.
    fut = loop.create_future()

    # Run "set_after()" coroutine in a parallel Task.
    # We are using the low-level "loop.create_task()" API here because
    # we already have a reference to the event loop at hand.
    # Otherwise we could have just used "asyncio.create_task()".
    loop.create_task(
        set_after(fut, 1, '... world'))

    print('hello ...')

    # Wait until *fut* has a result (1 second) and print it.
    print(await fut)

asyncio.run(main())

Важно

Будущий объект был спроектирован таким образом, чтобы имитировать concurrent.futures.Future. Ключевые отличия включают:

Вернуться на верх