Futures
Исходный код: 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 является awaitable (inspect.isawaitable()используется для проверки.)
Если obj не соответствует ни одному из вышеперечисленного, то генерируется
TypeError.Важно
См. также функцию
create_task(), которая является предпочтительным способом создания новых задач.Сохраняйте ссылку на результат этой функции, чтобы избежать исчезновения задачи во время выполнения.
Изменено в версии 3.5.1: Функция принимает любой awaitable объект.
Устарело начиная с версии 3.10: Выдаётся предупреждение об устаревании, если obj не является объектом, похожим на Future, и loop не указан, а текущей цикл событий нет.
-
аргумент obj как есть, если obj является
-
asyncio.wrap_future(future, *, loop=None) -
Оборачивает объект
concurrent.futures.Futureв объектasyncio.Future.Устарело начиная с версии 3.10: Выдаётся предупреждение об устаревании, если future не является объектом, похожим на Future, и loop не указан, а текущей цикл событий нет.
Объект Future
-
class asyncio.Future(*, loop=None) -
Объект Future представляет собой потенциальный результат асинхронной операции. Не потокобезопасен.
Future — это awaitable объект. Корутины могут ожидать выполнения 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 как выполненный и устанавливает его результат.
Вызывает ошибку
InvalidStateError, если Future уже выполнен.
-
set_exception(exception) -
Отмечает Future как выполненный и устанавливает исключение.
Вызывает ошибку
InvalidStateError, если Future уже выполнен.
-
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 выполнен.
Обратный вызов вызывается с объектом Future в качестве единственного аргумента.
Если Future уже выполнен при вызове этого метода, обратный вызов планируется с помощью
loop.call_soon().Необязательный ключевой аргумент context позволяет указать пользовательский
contextvars.Contextдля выполнения обратного вызова в нём. Текущий контекст используется, если 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. Ключевые различия включают:
- в отличие от asyncio Future, экземпляры
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(). - asyncio Future несовместим с функциями
concurrent.futures.wait()иconcurrent.futures.as_completed(). -
asyncio.Future.cancel()принимает необязательный параметрmsg, ноconcurrent.futures.cancel()нет.
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/asyncio-future.html