Infos réelles:
À partir de Python 3.7, asyncio.create_task(coro)une fonction de haut niveau a été ajoutée à cet effet.
Vous devriez l'utiliser à la place d'autres façons de créer des tâches à partir de coroutimes. Cependant, si vous avez besoin de créer une tâche arbitraire, vous devez utiliser asyncio.ensure_future(obj).
Anciennes infos:
ensure_future contre create_task
ensure_futureest une méthode pour créer à Taskpartir de coroutine. Il crée des tâches de différentes manières en fonction des arguments (y compris l'utilisation de create_taskpour les coroutines et les objets de type futur).
create_taskest une méthode abstraite de AbstractEventLoop. Différentes boucles d'événements peuvent implémenter cette fonction de différentes manières.
Vous devez utiliser ensure_futurepour créer des tâches. Vous n'en aurez besoin create_taskque si vous allez implémenter votre propre type de boucle d'événement.
Actualiser:
@ bj0 a souligné la réponse de Guido sur ce sujet:
Le but de ensure_future()est que si vous avez quelque chose qui pourrait être une coroutine ou un Future(ce dernier inclut un Taskparce que c'est une sous-classe de Future), et que vous voulez pouvoir appeler une méthode qui n'est définie que sur Future(probablement à propos du seul exemple utile étant cancel()). Quand c'est déjà un Future(ou Task) cela ne fait rien; quand c'est une coroutine, il l' enveloppe dans un Task.
Si vous savez que vous avez une coroutine et que vous souhaitez qu'elle soit planifiée, l'API correcte à utiliser est create_task(). Le seul moment où vous devriez appeler, ensure_future()c'est lorsque vous fournissez une API (comme la plupart des API d'Asyncio) qui accepte soit une coroutine, soit une Futureet que vous devez faire quelque chose qui vous oblige à avoir un Future.
et ensuite:
En fin de compte, je crois toujours que ensure_future()c'est un nom assez obscur pour une fonctionnalité rarement nécessaire. Lors de la création d'une tâche à partir d'une coroutine, vous devez utiliser le fichier
loop.create_task(). Peut-être qu'il devrait y avoir un alias pour ça
asyncio.create_task()?
Cela me surprend. Ma principale motivation à utiliser depuis le ensure_futuredébut était que sa fonction de niveau supérieur était comparée au membre de la boucle create_task(la discussion contient des idées telles que l'ajout asyncio.spawnou asyncio.create_task).
Je peux également souligner qu'à mon avis, il est assez pratique d'utiliser une fonction universelle qui peut gérer n'importe quelles Awaitablecoroutines plutôt que des coroutines.
Cependant, la réponse de Guido est claire: "Lorsque vous créez une tâche à partir d'une coroutine, vous devez utiliser le nom approprié loop.create_task()"
Quand les coroutines doivent-elles être enveloppées dans des tâches?
Envelopper la coroutine dans une tâche - est un moyen de démarrer cette coroutine "en arrière-plan". Voici un exemple:
import asyncio
async def msg(text):
await asyncio.sleep(0.1)
print(text)
async def long_operation():
print('long_operation started')
await asyncio.sleep(3)
print('long_operation finished')
async def main():
await msg('first')
# Now you want to start long_operation, but you don't want to wait it finised:
# long_operation should be started, but second msg should be printed immediately.
# Create task to do so:
task = asyncio.ensure_future(long_operation())
await msg('second')
# Now, when you want, you can await task finised:
await task
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Production:
first
long_operation started
second
long_operation finished
Vous pouvez remplacer asyncio.ensure_future(long_operation())par juste await long_operation()pour sentir la différence.
create_tasksi vous avez vraiment besoin d'un objet de tâche, dont vous ne devriez normalement pas avoir besoin: github.com/python/asyncio/issues/477#issuecomment-268709555