python3.8 RuntimeError: no running event loop

python3.8 RuntimeError: no running event loop

我从作者 caleb hattingh 的书中摘录了以下代码片段。我尝试了 运行 代码片段并遇到了这个错误。(练习中)

我该如何解决这个问题?

import asyncio

async def f(delay):
    await asyncio.sleep(1 / delay)
    return delay

loop = asyncio.get_event_loop()
for i in range(10):
    loop.create_task(f(i))

print(loop)
pending = asyncio.all_tasks()
group = asyncio.gather(*pending, return_exceptions=True)
results = loop.run_until_complete(group)
print(f'Results: {results}')
loop.close()

您必须将 loop 作为参数传递给 .all_tasks() 函数:

pending = asyncio.all_tasks(loop)

输出:

<_UnixSelectorEventLoop running=False closed=False debug=False>
<_GatheringFuture pending>
Results: [8, 5, 2, 9, 6, 3, ZeroDivisionError('division by zero'), 7, 4, 1]

因此,为了全面更正您的脚本:

import asyncio

async def f(delay):
    if delay:
        await asyncio.sleep(1 / delay)
    return delay

loop = asyncio.get_event_loop()
for i in range(10):
    loop.create_task(f(i))

print(loop)
pending = asyncio.all_tasks(loop)
group = asyncio.gather(*pending, return_exceptions=True)
results = loop.run_until_complete(group)
print(f'Results: {results}')
loop.close()

使用 python3.7 和更高版本,您可以省略事件循环和任务的显式创建和管理。 asyncio API 已经更改了几次,您会发现涵盖过时语法的教程。以下实现对应于您的解决方案。

import asyncio

async def f(delay):
    await asyncio.sleep(1 / delay)
    return delay

async def main():
    return await asyncio.gather(*[f(i) for i in range(10)], return_exceptions=True)

print(asyncio.run(main()))

输出

[ZeroDivisionError('division by zero'), 1, 2, 3, 4, 5, 6, 7, 8, 9]