异常"在新循环上运行时,线程'MainThread'中没有当前事件循环

San*_*Kim 7 python event-loop python-3.x python-asyncio python-3.5

这是简单的测试代码和结果.

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
Run Code Online (Sandbox Code Playgroud)
Traceback (most recent call last):
  File "test_test.py", line 11, in <module>
    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'.
Run Code Online (Sandbox Code Playgroud)

我运行async def test()了,new loop并期望asyncio.sleep(1)嵌套的test()也使用new loop.

与此相反,sleep()仍然似乎访问main loop我设置为None.

我知道我可以在调用之前将其重新设置main loopnew loopwith ,它将毫无例外地工作.asyncio.set_event_loop(loop)run_until_complete()

但是,我想知道必须设置并且用于协同程序是正常的asyncio,main loop无论循环何时运行协同程序.

use*_*342 6

我想知道asyncio该主循环是正常的,无论协程运行在哪个循环上,都必须将其设置为用于协程。

在Python 3.6之前,这是必需的。原因是像这样的功能asyncio.sleep()需要事件循环才能loop.call_later()用来安排唤醒呼叫以完成未来。

从Python 3.6(或3.5.3,包括对问题的修复)开始,get_event_loop()从事件循环驱动的协程调用时,它总是返回驱动它的事件循环。结果,您的代码可以正常工作。

联机文档中未提及新行为,但在docstring中有

从协程或回调(例如,使用预定的call_soonAPI或类似的API进行调用)时,此函数将始终返回正在运行的事件循环。

  • 实际上,该功能是在Python 3.6中引入的,并已反向移植到3.5.3。该代码段使用3.5,我猜是3.5.2。 (2认同)