python python-3.x async-await coroutine python-3.5

¿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.