Spec-Zone.ru › Python 3.12

Объекты Future

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

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

Функции Future

asyncio.isfuture(obj)

Возвращает True, если obj является одним из следующих объектов:

  • экземпляром asyncio.Future,
  • экземпляром asyncio.Task,
  • объектом, подобным Future, с атрибутом _asyncio_future_blocking.

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

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

Возвращает:

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

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

Важно

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

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

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

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

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

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

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

Объект Future

class asyncio.Future(*, loop=None)

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

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

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

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

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

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

result()

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

Если Future завершён и его результат задан методом set_result(), возвращается значение результата.

Если Future завершён и для него задано исключение методом set_exception(), этот метод вызывает исключение.

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

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

set_result(result)

Помечает Future как завершённый и задаёт его результат.

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

set_exception(exception)

Помечает Future как завершённый и задаёт исключение.

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

done()

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

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

cancelled()

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

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

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

Добавляет обратный вызов, который будет выполнен после завершения Future.

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

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

Необязательный аргумент context, доступный только по имени, позволяет указать пользовательский contextvars.Context, в котором будет выполняться callback. Если аргумент 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)

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

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

cancel(msg=None)

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

Если Future уже завершён или отменён, возвращает False. В противном случае состояние Future меняется на отменённое, планируется выполнение обратных вызовов и возвращается True.

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

exception()

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

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

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

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

get_loop()

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

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

В этом примере создаётся объект Future, создаётся и планируется асинхронная задача для задания результата Future, после чего программа ожидает, пока у 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())

Важно

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

  • в отличие от объектов Future в asyncio, экземпляры concurrent.futures.Future нельзя ожидать.
  • asyncio.Future.result() и asyncio.Future.exception() не принимают аргумент timeout.
  • asyncio.Future.result() и asyncio.Future.exception() вызывают исключение InvalidStateError, если Future не завершён.
  • Обратные вызовы, зарегистрированные с помощью asyncio.Future.add_done_callback(), не вызываются немедленно. Вместо этого их выполнение планируется с помощью loop.call_soon().
  • Future в asyncio несовместим с функциями concurrent.futures.wait() и concurrent.futures.as_completed().
  • asyncio.Future.cancel() принимает необязательный аргумент msg, а concurrent.futures.Future.cancel() — нет.

© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/asyncio-future.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API