Футуры¶
Объекты футуры используются для соединения низкоуровневого кода, основанного на обратном вызове, с высокоуровневым async/await кодом.
Функции футуры¶
-
asyncio.
isfuture
(obj)¶ Возвращает
True
, если obj является одним из:- Экземпляром
asyncio.Future
, - Экземпляром
asyncio.Task
, - Футуроподобным объектом с атрибутом
_asyncio_future_blocking
.
Добавлено в версии 3.5.
- Экземпляром
-
asyncio.
ensure_future
(obj, *, loop=None)¶ Возвращает:
- Аргумент obj как есть, если obj —
Future
,Task
или объект, подобный футуре (для проверки используетсяisfuture()
) - Объект
Task
, оборачивающий obj, если obj — корутина (для проверки используетсяiscoroutine()
); в этом случае корутина будет запланированаensure_future()
. - Объект
Task
, который будет ожидать на obj, если obj является ожидаемым (для проверки используетсяinspect.isawaitable()
)
Если obj не соответствует ни одному из вышеперечисленных, возникает
TypeError
.Важно
См. также функцию
create_task()
, которая является предпочтительным способом создания новых задач.Изменено в версии 3.5.1: Функция принимает любой ожидаемый объект.
- Аргумент obj как есть, если obj —
-
asyncio.
wrap_future
(future, *, loop=None)¶ Обернуть объект
concurrent.futures.Future
в объектasyncio.Future
.
Объект футуры¶
-
class
asyncio.
Future
(*, loop=None)¶ Футура представляет собой конечный результат асинхронной операции. Не потокобезопасный.
Футура — это ожидаемый объект. Корутины могут ожидать на объектах футуры до тех пор, пока у них не будет установлен результат или исключение, или пока они не будут отменены.
Обычно футуры используются для включения низкоуровневого кода на основе обратного вызова (например, в протоколах, реализованных с использованием asyncio транспортов) для взаимодействия с высокоуровневым async/await кодом.
Практическое правило — никогда не раскрывать объекты футуры в API- интерфейсах, ориентированных на пользователя, и рекомендуемый способ создания объекта футуры — это вызвать
loop.create_future()
. Таким образом, альтернативные реализации событийного цикла могут внедрять свои собственные оптимизированные реализации объекта футуры.Изменено в версии 3.7: Добавлена поддержка модуля
contextvars
.-
result
()¶ Возвращает результат футуры.
Если футура — выполнена и у неё есть результат, установленный методом
set_result()
, возвращается значение результата.Если футура выполнена и у неё есть исключение, установленное методом
set_exception()
, этот метод вызывает исключение.Если футура была отменена, этот метод вызывает исключение
CancelledError
.Если результат футуры ещё не доступна, этот метод вызывает исключение
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)¶ Добавить обратный вызов, который будет запускаться, когда футура будет выполнена.
callback вызывается с объектом футуры в качестве единственного аргумента.
Если футура уже выполнена при вызове этого метода, обратный вызов запланирован с
loop.call_soon()
.Необязательный аргумент context, содержащий только ключевой аргумент, позволяет указать пользовательский
contextvars.Context
для callback, в котором будет работать. Используется текущий контекст, когда context не указан.functools.partial()
может использоваться для передачи параметров функции обратного вызова, например:# Вызов 'print("Future:", fut)' когда "fut" выполнен. fut.add_done_callback( functools.partial(print, "Future:"))
Изменено в версии 3.7: Добавлен параметр context, содержащий только ключевой аргумент. См. PEP 567 для получения более подробной информации.
-
remove_done_callback
(callback)¶ Удалить callback из списка обратных вызовов.
Возвращает количество удаленных обратных вызовов, которое обычно равно 1, если обратный вызов не был добавлен более одного раза.
-
cancel
()¶ Отменить футуру и запланировать обратные вызовы.
Если футура уже выполнена или отменена, возвращает
False
. В противном случае изменит состояние футуры на отменена, запланирует обратные вызовы и возвращаетTrue
.
-
exception
()¶ Возвращает исключение, которое было установлено для этой футуры.
Исключение (или
None
, если исключение не было установлено) возвращается, только если футура выполнена.Если футура был отменена, этот метод вызывает исключение
CancelledError
.Если футура ещё не выполнена, этот метод вызывает исключение
InvalidStateError
.
-
get_loop
()¶ Возвращает событийный цикл, к которому привязан объект футуры.
Добавлено в версии 3.7.
-
В этом примере создаётся объект футуры, создаётся и планируется асинхронная задача, чтобы установить результат для футуры, и ожидает, пока футура не получит результат:
async def set_after(fut, delay, value):
# Спать *delay* секунд.
await asyncio.sleep(delay)
# Установить *value* как результат *fut* Футуры.
fut.set_result(value)
async def main():
# Получить текущий событийный цикл.
loop = asyncio.get_running_loop()
# Создание объекта футуры.
fut = loop.create_future()
# Запуск "set_after()" корутину в параллельной задаче.
# Мы используем низкоуровневое "loop.create_task()" API потому что
# у нас уже есть ссылка на событийный цикл под рукой.
# В противном случае мы могли бы просто использовать "asyncio.create_task()".
loop.create_task(
set_after(fut, 1, '... world'))
print('hello ...')
# Подождать, пока *fut* не получит результат (1 секунда) и распечатать его.
print(await fut)
asyncio.run(main())
Важно
Объект футуры был разработан для имитации concurrent.futures.Future
. Основные отличия:
- В отличие от asyncio футуры, сущности
concurrent.futures.Future
нельзя ожидать. asyncio.Future.result()
иasyncio.Future.exception()
не принимают аргумент timeout.asyncio.Future.result()
иasyncio.Future.exception()
вызывают исключениеInvalidStateError
, когда футура не выполнена.- Вызовы, зарегистрированные в
asyncio.Future.add_done_callback()
, вызываются не сразу. Вместо них планируетсяloop.call_soon()
. - asyncio футура несовместима с функциями
concurrent.futures.wait()
иconcurrent.futures.as_completed()
.