将函数列表及其相应参数传递给另一个函数

时间:2017-09-13 10:50:39

标签: python function kwargs

我正在努力传递一系列具有相应参数列表的函数。我还检查了here,但它没有用。例如(一种无效的天真方法):

def foo(data, functions_list, **kwarg):
    for func_i in functions_list:
        print func_i(data, **kwarg)

def func_1(data, par_1):
    return some_function_1(data, par_1)

def func_2(data, par_2_0, par_2_1):
    return some_function_2(data, par_2_0, par_2_1)

foo(data, [func_1, func_2], par_1='some_par', par_2_0=5, par_2_1=11)

重要par_1中无法使用func_2,因此每个函数都会使用一组唯一的参数。

7 个答案:

答案 0 :(得分:3)

您可以使用函数的名称作为关键字参数。索引kwargs时,您会使用func_i.__name__作为密钥。

def foo(data, function_list, **kwargs):
    for func_i in function_list:
        print(func_i(data, kwargs[func_i.__name__]))

现在,

foo(data, [func_1, func_2], func_1='some_par', func_2=[5, 11])

答案 1 :(得分:3)

您可以使用inspect.getargspec(我假设您使用Python 2,您不应该在Python 3中使用该函数,因为它已被弃用)以找出函数具有哪些参数名称并构建新的字典在那些:

import inspect

def foo(data, functions_list, **kwargs):
    for func_i in functions_list:
        newkwargs = {name: kwargs[name] 
                     for name in inspect.getargspec(func_i).args 
                     if name in kwargs}
        print(func_i(data, **newkwargs))

def func_1(data, par_1):
    return data, par_1

def func_2(data, par_2_0, par_2_1):
    return data, par_2_0, par_2_1

>>> data = 10
>>> foo(data, [func_1, func_2], par_1='some_par', par_2_0=5, par_2_1=11)
(10, 'some_par')
(10, 5, 11)

但更好的方法是简单地将参数与不依赖内省的函数相关联。

答案 2 :(得分:2)

如果你想保持foo函数具有完全相同的声明,并且你不介意每个函数接收整套参数,你可以这样做:

您只需要在每个'my_*'函数中添加**kwargs参数。

def foo(data, functions_list, **kwargs):
    for my_function in functions_list:
        print(my_function(data, **kwargs))


def my_sum(a, b, **kwargs):
    return a + b


def my_sub(a, c, **kwargs):
    return a - c


foo(0, [my_sum, my_sub], b=3, c=10)

Python会自动解析设置kwargs参数的b and c {。}}

答案 3 :(得分:1)

一种方法是将foo的第3个参数作为位置参数,并传入带有函数列表的args列表:

def foo(data, functions_list, args):
    for func, arg in zip(functions_list, args):
        print(func(data, arg))


def func1(data, par_1):
    return 'func1 called with {}'.format(par_1)


def func2(data, par_2):
    return 'func2 called with {}'.format(par_2)

foo('some_data', [func1, func2],
    [
        {'par_1_1': 11, 'par_1_2': 12},
        {'par_2_1': 21, 'par_2_2': 22}
    ])

zip()用于将每个函数与相应的参数映射。

<强>输出:

func1 called with {'par_1_1': 11, 'par_1_2': 12}
func2 called with {'par_2_1': 21, 'par_2_2': 22}

答案 4 :(得分:1)

另一种方法可以是这样的:

def foo(data, function_list, **kwargs):
    function_dict = {
        "func_1": func_1,
        "func_2": func_2        
    }
    for func_i in function_list:
        print function_dict[func_i](data, **kwargs)

def func_1(data, **arg):
    filtered_argument = {key: value for key, value in arg.items() if key.startswith('par_1')}
    return list([data, filtered_argument])

def func_2(data, **arg):
    filtered_argument = {key: value for key, value in arg.items() if key.startswith('par_2_')}
    return list([data, filtered_argument])


data = [1,2,3]  
foo(data, ['func_1', 'func_2'], par_1='some_par', par_2_0=5, par_2_1=11)

输出:

[[1, 2, 3], {'par_1': 'some_par'}]
[[1, 2, 3], {'par_2_0': 5, 'par_2_1': 11}]

我确信您可以通过这种方式即兴创作当前的代码。

答案 5 :(得分:1)

我喜欢@ COLDSPEED的方法,但想提出另一个解决方案。总是传递3个值:function,args,keyword args:

用法:

foo(
    func_1, ('some_par',), {},
    func_2, (5, 11), {},
)

实现(Python3语法):

def foo(*args3):
    while args3:
        func, args, kwargs, *args3 = args3
        func(*args, **kwargs)

答案 6 :(得分:1)

你可以这样做,“关闭”列表项中的函数的每个参数,然后让“foo”向后拆分:

def foo(data, functions_list, kwarg):
    for func_i, args in zip(functions_list, kwarg):
        func_i(data, **args)


def func_1(data, par_1):
    print("func_1 %s %s" % (data, par_1))


def func_2(data, par_2_0, par_2_1):
    print("func_2 %s "
          "%s %s" % (data, par_2_0, par_2_1))

data = "Some Data"

foo(data, [func_1, func_2], [{"par_1":'some_par'}, {"par_2_0":5, "par_2_1":11}])