Excepción “No hay un bucle de eventos actual en el hilo ‘MainThread'” mientras se ejecuta en un nuevo bucle

El es el código de prueba simple y el resultado.

import asyncio async def test(): await asyncio.sleep(1) if __name__ == '__main__': asyncio.set_event_loop(None) # Clear the main loop. loop = asyncio.new_event_loop() # Create a new loop. loop.run_until_complete(test()) # Run coroutine over the new loop 

 Traceback (most recent call last): File "test_test.py", line 11, in  loop.run_until_complete(test()) File "/usr/lib/python3.5/asyncio/base_events.py", line 387, in run_until_complete return future.result() File "/usr/lib/python3.5/asyncio/futures.py", line 274, in result raise self._exception File "/usr/lib/python3.5/asyncio/tasks.py", line 239, in _step result = coro.send(None) File "test_test.py", line 5, in test await asyncio.sleep(1) File "/usr/lib/python3.5/asyncio/tasks.py", line 510, in sleep loop = events.get_event_loop() File "/usr/lib/python3.5/asyncio/events.py", line 632, in get_event_loop return get_event_loop_policy().get_event_loop() File "/usr/lib/python3.5/asyncio/events.py", line 578, in get_event_loop % threading.current_thread().name) RuntimeError: There is no current event loop in thread 'MainThread'. 

asyncio.sleep(1) async def test() sobre el new loop y esperaba que asyncio.sleep(1) que está nested por test() también use el new loop .

En contraste con eso, sleep() todavía parece acceder al main loop que configuré como None .

Sé que puedo restablecer un main loop como el new loop con asyncio.set_event_loop(loop) antes de llamar a run_until_complete() y funcionará sin excepción.

Sin embargo, quiero saber que es normal para asyncio que se asyncio el main loop y que se use para las rutinas independientemente de un bucle en el que se ejecute la rutina.

Quiero saber que es normal para asyncio que se asyncio el bucle principal y que se use para las rutinas independientemente de un bucle en el que se ejecute la rutina.

Esto solía ser requerido antes de Python 3.6. La razón es que las funciones como asyncio.sleep() necesitan un bucle de eventos para poder usar loop.call_later() para progtwigr una llamada de loop.call_later() para completar el futuro.

A partir de Python 3.6 (o 3.5.3, que incluía una solución para el problema ), cuando se invoca get_event_loop() desde una rutina dirigida por un bucle de eventos, siempre devuelve el bucle de eventos que lo impulsa. Como resultado, su código funciona correctamente.

Esto está cubierto por la siguiente oración en la documentación :

Se produce una excepción a esta regla cuando se llama a get_event_loop() desde un futuro / coroutine en ejecución, en cuyo caso devolverá el bucle actual que ejecuta ese futuro / coroutine.