Будущее¶
Исходный код: 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
. Ключевые отличия включают:
в отличие от фьючерсов 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 Future несовместим с функциями
concurrent.futures.wait()
иconcurrent.futures.as_completed()
.asyncio.Future.cancel()
принимает необязательный аргументmsg
, аconcurrent.futures.Future.cancel()
- нет.