Будущее¶
Исходный код: 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()- нет.