繁体   English   中英

如何从异步列表中同时运行任务? (Python 3.7 及更高版本)

[英]How to run tasks concurrently from a list in asyncio? (Python 3.7 and above)

在 asyncio 的官方文档中:

import asyncio

async def factorial(name, number):
    f = 1
    for i in range(2, number + 1):
        print(f"Task {name}: Compute factorial({i})...")
        await asyncio.sleep(1)
        f *= i
    print(f"Task {name}: factorial({number}) = {f}")

async def main():
    # Schedule three calls *concurrently*:
    await asyncio.gather(
        factorial("A", 2),
        factorial("B", 3),
        factorial("C", 4),
    )

asyncio.run(main())
 Expected output:

 Task A: Compute factorial(2)...
 Task B: Compute factorial(2)...
 Task C: Compute factorial(2)...
 Task A: factorial(2) = 2
 Task B: Compute factorial(3)...
 Task C: Compute factorial(3)...
 Task B: factorial(3) = 6
 Task C: Compute factorial(4)...
 Task C: factorial(4) = 24

假设,我们通过删除参数名称进一步简化这个 function阶乘

async def factorial(number):
    f = 1
    for i in range(2, number + 1):
        print(f"Task {number}: Compute factorial({i})...")
        await asyncio.sleep(1)
        f *= i
    print(f"Task {number}: factorial({number}) = {f}")

并且说,我有一个巨大的数字列表来调用这个阶乘function,所以我写下这个 function 在asyncio.gather()

    await asyncio.gather(
        factorial(2),
        factorial(3),
        factorial(4),
        factorial(5),
        ...
        ...
        ...
        factorial(N),
    )

出于试用目的,我的尝试是这样的:

async def main():

    numList = [2,3,4]
    
    await asyncio.gather(
        factorial(num) for num in numList
    )

asyncio.run(main())

不幸的是得到以下错误:

    RuntimeWarning: coroutine 'factorial' was never awaited
    RuntimeError: Task got bad yield: <coroutine object factorial at 0x102c95b00>

TL;博士

如何从列表中同时运行异步任务?

PS 我会支持使用新的 asyncio 方法的解决方案,比如runcreate_task 并且会按照官方文档中关于event_loop的劝阻

要从列表中运行协程,您需要将它们解压缩gather中,因为根据文档gather使用了aws参数的包装。

    await asyncio.gather(*[factorial(num) for num in numList])

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM