Фьючерсы¶
Код источника: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py
Объекты Future используются для соединения низкоуровневого кода, основанного на обратных вызовах, с высокоуровневым кодом async/await.
Будущие функции¶
- asyncio.isfuture(obj)¶
Возвращает
True
, если obj является одним из:экземпляр
asyncio.Future
,экземпляр
asyncio.Task
,объект типа Future с атрибутом
_asyncio_future_blocking
.
Added in version 3.5.
- asyncio.ensure_future(obj, *, loop=None)¶
Возвращение:
Аргумент obj как есть, если obj - это
Future
,Task
или объект типа Future (isfuture()
используется для теста).объект
Task
, оборачивающий obj, если obj - это coroutine (для теста используется:func:iscoroutine); в этом случае coroutine будет запланированensure_future()
.объект
Task
, который будет ожидать obj, если obj является ожидаемым (inspect.isawaitable()
используется для теста).
Если obj не является ни одним из вышеперечисленных, возникает сообщение
TypeError
.Важно
См. также функцию
create_task()
, которая является предпочтительным способом создания новых Задач.Сохраните ссылку на результат этой функции, чтобы избежать исчезновения задачи в середине выполнения.
Изменено в версии 3.5.1: Функция принимает любой объект awaitable.
Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если obj не является Future-like объектом, а loop не указан и нет запущенного цикла событий.
- asyncio.wrap_future(future, *, loop=None)¶
Заверните объект
concurrent.futures.Future
в объектasyncio.Future
.Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если future не является Future-подобным объектом, а loop не указан и нет запущенного цикла событий.
Будущий объект¶
- class asyncio.Future(*, loop=None)¶
Future представляет собой конечный результат асинхронной операции. Не является потокобезопасным.
Future - это объект awaitable. Короткие программы могут ожидать объекты Future до тех пор, пока не получат результат или исключение, или пока не будут отменены. Future можно ожидать несколько раз, и результат будет одинаковым.
Обычно Futures используются для того, чтобы низкоуровневый код, основанный на обратных вызовах (например, в протоколах, реализованных с помощью asyncio transports), мог взаимодействовать с высокоуровневым кодом async/await.
Правило заключается в том, чтобы никогда не раскрывать объекты Future в пользовательских API, и рекомендуемый способ создания объекта Future - это вызов
loop.create_future()
. Таким образом, альтернативные реализации циклов событий смогут внедрить свои собственные оптимизированные реализации объекта Future.Изменено в версии 3.7: Добавлена поддержка модуля
contextvars
.Не рекомендуется, начиная с версии 3.10: Предупреждение об устаревании выдается, если не указан loop и нет запущенного цикла событий.
- result()¶
Возвращает результат выполнения Future.
Если Future выполнено и результат установлен методом
set_result()
, возвращается значение результата.Если Future выполнено и имеет исключение, установленное методом
set_exception()
, этот метод поднимает исключение.Если будущее было отменено, этот метод вызывает исключение
CancelledError
.Если результат Future еще не доступен, этот метод вызывает исключение
InvalidStateError
.
- set_result(result)¶
Пометьте будущее как выполненное и установите его результат.
Вызывает ошибку
InvalidStateError
, если будущее уже выполнено.
- set_exception(exception)¶
Пометьте будущее как выполненное и установите исключение.
Вызывает ошибку
InvalidStateError
, если будущее уже выполнено.
- done()¶
Возвращает
True
, если будущее закончено.Будущее считается выполненным, если оно было отменено или если оно имеет результат или исключение, установленное с помощью вызовов
set_result()
илиset_exception()
.
- cancelled()¶
Возвращает
True
, если будущее было отменено.Метод обычно используется для проверки того, не является ли Future отмененным, прежде чем установить для него результат или исключение:
if not fut.cancelled(): fut.set_result(42)
- add_done_callback(callback, *, context=None)¶
Добавьте обратный вызов, который будет выполняться, когда будущее будет закончено.
Вызывается обратный вызов с объектом 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: Добавлен параметр контекст, который зависит только от ключевого слова. Более подробную информацию см. в разделе PEP 567.
- remove_done_callback(callback)¶
Удалите callback из списка обратных вызовов.
Возвращает количество удаленных обратных вызовов, которое обычно равно 1, если только обратный вызов не был добавлен более одного раза.
- cancel(msg=None)¶
Отмените будущее и запланируйте обратные вызовы.
Если будущее уже выполнено или отменено, верните
False
. В противном случае измените состояние будущего на отменено, запланируйте обратные вызовы и вернитеTrue
.Изменено в версии 3.9: Добавлен параметр msg.
- exception()¶
Возвращает исключение, которое было установлено для этого Future.
Исключение (или
None
, если исключение не было задано) возвращается только в том случае, если Future done.Если будущее было отменено, этот метод вызывает исключение
CancelledError
.Если будущее еще не закончено, этот метод вызывает исключение
InvalidStateError
.
- get_loop()¶
Возвращает цикл событий, к которому привязан объект Future.
Added in version 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 Futures, экземпляры
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.Future.cancel()
- нет.