Futures¶
Code source : Lib/asyncio/futures.py, Lib/asyncio/base_futures.py
Les objets Future sont utilisés comme passerelles entre du code bas niveau basé sur des fonctions de rappel et du code haut niveau utilisant async et await.
Fonctions pour Future¶
- asyncio.isfuture(obj)¶
Renvoie
True
si obj est soit :une instance de
asyncio.Future
;une instance de
asyncio.Task
;un objet se comportant comme Future et possédant un attribut
_asyncio_future_blocking
.
Ajouté dans la version 3.5.
- asyncio.ensure_future(obj, *, loop=None)¶
Renvoie :
l'objet obj tel quel si c'est un objet
Future
,Task
ou se comportant comme un Future.isfuture()
est utilisée pour le test ;un objet
Task
encapsulant obj si ce dernier est une coroutine (iscoroutine()
est utilisée pour le test). Dans ce cas, l’exécution de la coroutine sera planifiée parensure_future()
;un objet
Task
qui attendra (await) obj si ce dernier peut être attendu (awaitable).iscoroutine()
est utilisée pour le test.
Si obj ne correspond à aucun des critères ci-dessus, une exception
TypeError
est levée.Important
Voir aussi la fonction
create_task()
qui est la manière privilégiée pour créer des nouvelles tâches.Gardez une référence au résultat de cette fonction pour éviter de voir une tâche disparaitre au milieu de son exécution.
Modifié dans la version 3.5.1: La fonction accepte n'importe quel objet awaitable.
Obsolète depuis la version 3.10: Un
DeprecationWarning
est levé si obj n'est pas un objet se comportant comme un Future, si loop n'est pas spécifié et s'il n'y a pas de boucle d'évènements en cours d'exécution.
- asyncio.wrap_future(future, *, loop=None)¶
Encapsule un objet
concurrent.futures.Future
dans un objetasyncio.Future
.Obsolète depuis la version 3.10: Un
DeprecationWarning
est levé si future n'est pas un objet se comportant comme un Future, si loop n'est pas spécifié et s'il n'y a pas de boucle d'évènements en cours d'exécution.
Objet Future¶
- class asyncio.Future(*, loop=None)¶
Un Future représente le résultat final d'une opération asynchrone. Il n'est pas conçu pour pouvoir être utilisé par plusieurs fils d'exécution.
Future est un objet qui peut être attendu (awaitable). Les coroutines peuvent attendre les objets Future jusqu'à ce qu'ils renvoient un résultat, ils lèvent une exception ou qu'ils soient annulés. Un Future peut être attendu plusieurs fois et le résultat est le même.
Les Futures sont habituellement utilisés pour permettre à du code bas niveau basé sur des fonctions de rappel (par exemple : les protocoles utilisant asyncio transports) d'interagir avec du code haut niveau utilisant async et await.
Une bonne règle empirique est de ne jamais exposer des objets Future dans des API destinées à l'utilisateur. La façon privilégiée de créer des objets Future est d'appeler la méthode
loop.create_future()
. Cela permet aux implémentations alternatives de la boucle d'évènements d'utiliser leur propre implémentation de l'objet Future.Modifié dans la version 3.7: Ajout du support du module
contextvars
.Obsolète depuis la version 3.10: Un
DeprecationWarning
est levé si loop n'est pas spécifié et s'il n'y a pas de boucle d'évènements en cours d'exécution.- result()¶
Renvoie le résultat du Future.
Si le Future est « terminé » et a un résultat défini par la méthode
set_result()
, ce résultat est renvoyé.Si le Future est « terminé » et a une exception définie par la méthode
set_exception()
, cette méthode lève l'exception.Si le Future a été annulé, cette méthode lève une exception
CancelledError
.If the Future's result isn't yet available, this method raises an
InvalidStateError
exception.
- set_result(result)¶
Marque le Future comme « terminé » et définit son résultat.
Raises an
InvalidStateError
error if the Future is already done.
- set_exception(exception)¶
Marque le Future comme « terminé » et définit une exception.
Raises an
InvalidStateError
error if the Future is already done.
- done()¶
Renvoie
True
si le Future est « terminé ».Un Future est « terminé » s'il a été « annulé » ou si un résultat ou une exception a été définie par les méthodes
set_result()
ouset_exception()
.
- cancelled()¶
Renvoie
True
si le Future a été « annulé ».Cette méthode est habituellement utilisée pour vérifier qu'un Future n'est pas « annulé » avant de définir un résultat ou une exception pour celui-ci :
if not fut.cancelled(): fut.set_result(42)
- add_done_callback(callback, *, context=None)¶
Ajoute une fonction de rappel à exécuter lorsque le Future est « terminé ».
L'argument callback est appelé avec l'objet Future comme seul argument.
Si le Future est déjà « terminé » lorsque la méthode est appelée, l'exécution de la fonction de rappel est planifiée avec
loop.call_soon()
.L'argument nommé optionnel context permet de spécifier une classe
contextvars.Context
personnalisée dans laquelle la fonction de rappel s’exécutera. Le contexte actuel est utilisé si context n'est pas fourni.functools.partial()
peut être utilisée pour passer des paramètres à la fonction de rappel :# Call 'print("Future:", fut)' when "fut" is done. fut.add_done_callback( functools.partial(print, "Future:"))
Modifié dans la version 3.7: Ajout de l'argument nommé context. Voir PEP 567 pour plus de détails.
- remove_done_callback(callback)¶
Retire callback de la liste de fonctions de rappel.
Renvoie le nombre de fonctions de rappel retiré. La méthode renvoie généralement 1, à moins que la fonction ait été ajoutée plus d'une fois.
- cancel(msg=None)¶
Annule le Future et planifie l'exécution des fonctions de rappel.
Si le Future est déjà « terminé » ou « annulé », renvoie
False
. Autrement, change l'état du Future à « annulé », planifie l'exécution des fonctions de rappel et renvoieTrue
.Modifié dans la version 3.9: Ajout du paramètre msg.
- exception()¶
Renvoie l'exception définie pour ce Future.
L'exception, ou
None
si aucune exception n'a été définie, est renvoyé seulement si le Future est « terminé ».Si le Future a été annulé, cette méthode lève une exception
CancelledError
.Si le Future n'est pas encore « terminé », cette méthode lève une exception
InvalidStateError
.
- get_loop()¶
Renvoie la boucle d'évènements à laquelle le Future est attaché.
Ajouté dans la version 3.7.
Cet exemple crée un objet Future, puis crée et planifie l’exécution d'une tâche asynchrone qui définira le résultat du Future et attend jusqu'à ce que le Future ait un résultat :
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())
Important
L'objet Future est conçu pour imiter la classe concurrent.futures.Future
. Les principales différences sont :
contrairement au Future asyncio, les instances de
concurrent.futures.Future
ne peuvent pas être attendues ;asyncio.Future.result()
etasyncio.Future.exception()
n'acceptent pas d'argument timeout ;asyncio.Future.result()
etasyncio.Future.exception()
lèvent une exceptionInvalidStateError
lorsque le Future n'est pas « terminé » ;les fonctions de rappel enregistrées à l'aide de
asyncio.Future.add_done_callback()
ne sont pas exécutées immédiatement mais planifiées avecloop.call_soon()
;les Future asyncio ne sont pas compatibles avec les fonctions
concurrent.futures.wait()
etconcurrent.futures.as_completed()
;asyncio.Future.cancel()
accepts an optionalmsg
argument, butconcurrent.futures.Future.cancel()
does not.