Python - Asyncio - 将参数列表传递给使用 * 定义的函数

jim*_*iat 5 python python-asyncio

让我们考虑文档中的以下示例:

import asyncio

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

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
    factorial("A", 2),
    factorial("B", 3),
    factorial("C", 4),
))
loop.close()
Run Code Online (Sandbox Code Playgroud)

模块中的 Gather 函数如下所示:

asyncio.gather(*coros_or_futures, loop=None, return_exceptions=False)
Run Code Online (Sandbox Code Playgroud)

它一切正常,但对于我的现实生活中的问题,我需要传入的不是带有硬编码参数的函数的多样性,而是创建多个函数的某种形式的元组理解。

我试过:

loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(
    [factorial(str(g),g) for g in range(3)]
))
loop.close()
Run Code Online (Sandbox Code Playgroud)

但它不起作用。任何人都知道如何使用该收集函数来处理以编程方式创建的函数列表?

gather要清楚:该函数不是由我定义的,所以我不能从它的定义中删除 * 并简单地传递这样的参数列表。我需要“解压缩”列表,但我不知道如何。

Yuv*_*uss 6

您还可以将itertools.starmap用于此任务:

import asyncio
import itertools

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

loop = asyncio.get_event_loop()

args = [(str(g), g) for g in range(3)]
tasks = itertools.starmap(factorial, args)
loop.run_until_complete(asyncio.gather(*tasks))
loop.close()
Run Code Online (Sandbox Code Playgroud)

制作一个迭代器,使用从可迭代对象获得的参数来计算函数。当参数参数已经从单个可迭代对象分组到元组中时(数据已经“预压缩”),用于代替 map()。

更多阅读:这里


jim*_*iat 5

找到了解决方案:

loop.run_until_complete(asyncio.gather(*(factorial(str(g),g) for g in range(3)))
Run Code Online (Sandbox Code Playgroud)