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))?