Python - Asyncio - 将参数列表传递给使用*

时间:2017-06-25 10:39:35

标签: 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()

收集功能在模块中显示:

asyncio.gather(*coros_or_futures, loop=None, return_exceptions=False)

它的工作正常,但对于我的现实生活中的问题,我需要传递聚集函数而不是带有硬编码参数的多种函数,而是通过某种形式创建多个函数的元组理解。

我试过了:

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

但它不起作用。任何人都知道如何使用聚合函数来编写一个以编程方式创建的函数列表?

要清除:我没有定义gather函数,因此我无法从其定义中删除*并简单地传递这样的参数列表。我需要"解包"列表,但我不知道如何。

3 个答案:

答案 0 :(得分:3)

您还可以使用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()
  

创建一个迭代器,使用从iterable获得的参数计算函数。当参数参数已经从单个可迭代的元组中分组时(数据已被“预压缩”),使用而不是map()。

更多阅读:here

答案 1 :(得分:1)

找到解决方案:

loop.run_until_complete(asyncio.gather(*(factorial(str(g),g) for g in range(3)))

答案 2 :(得分:1)

协程列表可以按以下方式动态生成和传递:

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():
    a = factorial("A", 2)
    b = factorial("B", 3)
    c = factorial("C", 4)
    #
    # example passing in list of coroutines
    #
    await asyncio.gather(*[a,b,c])

asyncio.run(main())