¿Cómo usar async/await en Python 3.5?
python-3.x async-await (2)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import time
async def foo():
await time.sleep(1)
foo()
No podría hacer que este simple ejemplo muerto se ejecute:
RuntimeWarning: coroutine ''foo'' was never awaited foo()
Ejecutar corutinas requiere un
bucle de eventos
.
Use la
biblioteca
asyncio()
para crear uno:
import asyncio
# Python 3.7+
asyncio.run(foo())
o
# Python 3.6 and older
loop = asyncio.get_event_loop()
loop.run_until_complete(foo())
Consulte también el
capítulo
Tareas y Corutinas
de la documentación de
asyncio
.
Si ya tiene un bucle en ejecución, desearía ejecutar corutinas adicionales al mismo tiempo creando una tarea (
asyncio.create_task(...)
en Python 3.7+,
asyncio.ensure_future(...)
en versiones anteriores).
Sin embargo,
time.sleep()
cuenta que
time.sleep()
no
es un objeto esperable.
No devuelve
None
por lo que obtiene una excepción después de 1 segundo:
>>> asyncio.run(foo())
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/.../lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/.../lib/python3.7/asyncio/base_events.py", line 573, in run_until_complete
return future.result()
File "<stdin>", line 2, in foo
TypeError: object NoneType can''t be used in ''await'' expression
En este caso, debe utilizar la
asyncio.sleep()
su
lugar:
async def foo():
await asyncio.sleep(1)
que coopera con el bucle para permitir que se ejecuten otras tareas. Para bloquear el código de bibliotecas de terceros que no tienen equivalentes de asincio, puede ejecutar ese código en un grupo de ejecutores . Consulte Ejecución del código de bloqueo en la guía de desarrollo asyncio.
Si ya tiene un ciclo en ejecución (con algunas otras tareas), puede agregar nuevas tareas con:
asyncio.ensure_future(foo())
de lo contrario podría obtener
The event loop is already running
error.