Disons que nous avons une fonction factice:
async def foo(arg):
result = await some_remote_call(arg)
return result.upper()
Quelle est la différence entre:
import asyncio
coros = []
for i in range(5):
coros.append(foo(i))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(coros))
Et:
import asyncio
futures = []
for i in range(5):
futures.append(asyncio.ensure_future(foo(i)))
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(futures))
Remarque : l'exemple renvoie un résultat, mais ce n'est pas l'objet de la question. Lorsque la valeur de retour compte, utilisez à la gather()
place de wait()
.
Quelle que soit la valeur de retour, je recherche des éclaircissements sur ensure_future()
. wait(coros)
et les wait(futures)
deux exécutent les coroutines, alors quand et pourquoi une coroutine devrait-elle être enveloppée ensure_future
?
Fondamentalement, quelle est la bonne façon (tm) d'exécuter un tas d'opérations non bloquantes en utilisant Python 3.5 async
?
Pour un crédit supplémentaire, que faire si je souhaite regrouper les appels? Par exemple, je dois appeler some_remote_call(...)
1000 fois, mais je ne veux pas écraser le serveur Web / la base de données / etc. avec 1000 connexions simultanées. C'est faisable avec un thread ou un pool de processus, mais existe-t-il un moyen de le faire avecasyncio
?
Mise à jour 2020 (Python 3.7+) : n'utilisez pas ces extraits. Utilisez plutôt:
import asyncio
async def do_something_async():
tasks = []
for i in range(5):
tasks.append(asyncio.create_task(foo(i)))
await asyncio.gather(*tasks)
def do_something():
asyncio.run(do_something_async)
Pensez également à utiliser Trio , une alternative tierce robuste à asyncio.
ensure_future()
? Et si j'ai besoin du résultat, ne puis-je pas simplement l'utiliserrun_until_complete(gather(coros))
?