Асинхронные задачи
Исходный код: 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 является ожидаемым (inspect.isawaitable()используется для проверки).
Если obj не соответствует ни одному из вышеперечисленного, выбрасывается
TypeError.Важно
См. также функцию
create_task(), которая является предпочтительным способом создания новых задач.Сохраните ссылку на результат этой функции, чтобы предотвратить исчезновение задачи во время выполнения.
Изменено в версии 3.5.1: Функция принимает любой ожидаемый объект.
Устарело начиная с версии 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.Future.cancel()не принимает.
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/asyncio-future.html