简体   繁体   English

如何在指定* args或** kwargs的同时从函数字典运行函数

[英]How to run functions from a dict of functions while specifying *args or **kwargs

I basically want to run tasks that are gathered from a dict of functions. 我基本上想运行从功能字典收集的任务。 I'm using asyncio in my program but it probably doesn't matter for my question. 我在程序中使用了asyncio,但这对我的问题可能并不重要。 Here is my code to illustrate... 这是我的代码来说明...

import asyncio
import random


async def faketask(taskname):    # This is a function to simulate asynchronous tasks being performed.
    fakedelay = random.randint(1,6)
    print(f'{taskname} started (completing in {fakedelay} seconds)')
    await asyncio.sleep(fakedelay)
    print(f'{taskname} completed after {fakedelay} seconds')


async def main():
    tasklist = {    # This is a dict of tasks to be performed
    'Task-1': faketask,
    'Task-2': faketask,
    'Task-3': faketask,
    }

    _tasks = []
    for taskname in tasklist:
        _tasks.append(asyncio.ensure_future(tasklist[taskname](taskname)))
        print(f'Added {taskname} to job queue.')
    await asyncio.gather(*_tasks)


if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.close()

This works pretty well. 效果很好。 But I want to repeat certain tasks periodically, so I added some code to the faketask function. 但是我想定期重复执行某些任务,因此我向faketask函数添加了一些代码。

async def faketask(taskname, interval=None):
    fakedelay = random.randint(1,6)
    print(f'{taskname} started (completing in {fakedelay} seconds)')
    await asyncio.sleep(fakedelay)
    print(f'{taskname} completed after {fakedelay} seconds')
    if interval is not None:
        print(f'Repeating {taskname} in {interval} seconds')
        while True:
            await faketask(taskname, *args, **kwargs)
            await asyncio.sleep(interval)

This makes the function repeat by providing the kwarg interval with an integer. 通过为kwarg interval提供一个整数,使函数重复执行。 Future functions may also use additional *args and **kwargs. 将来的功能可能还会使用其他* args和** kwargs。

So I basically wish I could specify the repeat interval in the tasklist dict, eg 所以我基本上希望我可以在任务列表字典中指定重复间隔,例如

    tasklist = {
    'Task-1': faketask,
    'Task-2': faketask,
    'Task-3': faketask(interval=60),
    }

But that doesn't work because faketask() is missing 1 required positional argument: 'taskname'. 但这是行不通的,因为faketask()缺少1个必需的位置参数:“ taskname”。

Is there any clever way to solve this? 有什么聪明的方法可以解决这个问题吗?

And as a bonus question, the line _tasks.append(asyncio.ensure_future(tasklist[taskname](taskname))) looks a bit ugly, is there any way to pass the taskname argument automatically? 作为一个额外的问题, _tasks.append(asyncio.ensure_future(tasklist[taskname](taskname)))看起来有点难看,有没有办法自动传递taskname参数?

You can use functools.partial , which is designed exactly for situations like this: 您可以使用functools.partial ,它是专门为以下情况而设计的:

'Task-3': functools.partial(faketask, interval=60),

And as a bonus question, the line _tasks.append(asyncio.ensure_future(tasklist[taskname](taskname))) looks a bit ugly, is there any way to pass the taskname argument automatically? 作为一个额外的问题, _tasks.append(asyncio.ensure_future(tasklist[taskname](taskname)))看起来有点难看,有没有办法自动传递taskname参数?

You can use items() to remove the redundancy: 您可以使用items()删除冗余:

tasks = []
for taskname, taskfn in tasklist.items():
    tasks.append(taskfn(taskname))

The explicit call to asyncio.ensure_future is unnecessary because asyncio.gather does that automatically. 不需要显式调用asyncio.ensure_future ,因为asyncio.gather会自动执行此操作。 Also, I've renamed _tasks to just tasks . 另外,我改名_tasks只是tasks By convention, the _ in front of a variable name denotes that the variable will not be used in subsequent code, which is not the case here. 按照惯例,变量名前面的_表示该变量将不会在后续代码中使用,在这里不是这种情况。

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

相关问题 (*args,**kwargs) 函数的完成/智能感知 - completion/intellisense on (*args ,**kwargs) functions 如何在循环内定义 Python 函数并使用 *args 和 **kwargs - How to define Python functions inside a loop and use *args and **kwargs 在哪里可以找到函数的 kwargs/args 文档 - Where to find documentation of kwargs/args of functions 输出** kwargs,* args的__dict__类 - class __dict__ from output **kwargs, *args 具有** kwargs的功能 - Functions with **kwargs 从函数集合中获取各自的* args,** wargs,然后使用提供的1d参数填充不规则的2d结构 - Getting respective *args, **kwargs from collection of functions, then filling in the irregular 2d structure with provided 1d arguments 使用参数,关键字参数,* args,** kwargs与Python函数混淆 - Confusion with Python functions using an argument, keyword argument, *args, **kwargs 如何正确地将键/值参数的字典传递给 kwargs? - How to properly pass a dict of key/value args to kwargs? 如何使用类中的函数创建字典? - How to create a dict with functions from a class? 如何将 **kwargs 参数传递给相关的包装函数? - How to pass **kwargs parameters to the relevant wrapped functions?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM