Digamos que tenemos una función ficticia:
async def foo(arg):
result = await some_remote_call(arg)
return result.upper()
Cuál es la diferencia 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))
Y:
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))
Nota : El ejemplo devuelve un resultado, pero este no es el foco de la pregunta. Cuando el valor de retorno importa, use en gather()lugar de wait().
Independientemente del valor de retorno, busco claridad ensure_future(). wait(coros)y wait(futures)ambos ejecutan las corrutinas, entonces, ¿cuándo y por qué debería incluirse una corrutina ensure_future?
Básicamente, ¿cuál es la forma correcta (tm) de ejecutar un montón de operaciones sin bloqueo usando Python 3.5 async?
Para obtener crédito adicional, ¿qué sucede si quiero agrupar las llamadas? Por ejemplo, necesito llamar some_remote_call(...)1000 veces, pero no quiero aplastar el servidor web / base de datos / etc.con 1000 conexiones simultáneas. Esto es factible con un hilo o grupo de procesos, pero ¿hay alguna forma de hacerlo asyncio?
Actualización 2020 (Python 3.7+) : no use estos fragmentos. En su lugar use:
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)
También considere usar Trio , una alternativa sólida de terceros a asyncio.
ensure_future()? Y si necesito el resultado, ¿no puedo usarlorun_until_complete(gather(coros))?