I am struggling to pass a list of functions with a list of corresponding parameters. I also checked here, but it wasn't very helpful. for example (a naive approach which doesn't work):
我正在努力传递一系列具有相应参数列表的函数。我也在这里查了一下,但是没有用。例如(一种不起作用的天真方法):
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)
Importantly, par_1
cannot be used in func_2
, so each function consumes a unique set of parameters.
重要的是,par_1不能在func_2中使用,因此每个函数都使用一组唯一的参数。
7 个解决方案
#1
3
You could use the function's name as the keyword arguments. When indexing kwargs
, you'd use func_i.__name__
as the key.
您可以使用函数的名称作为关键字参数。索引kwargs时,你会使用func_i .__ name__作为键。
def foo(data, function_list, **kwargs):
for func_i in function_list:
print(func_i(data, kwargs[func_i.__name__]))
And now,
现在,
foo(data, [func_1, func_2], func_1='some_par', func_2=[5, 11])
#2
3
You could use inspect.getargspec
(I assume you use Python 2, you shouldn't use that function in Python 3 because it has been deprecated) to find out which argument names a function has and build a new dictionary based on those:
您可以使用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)
But a better way would be to simply associate parameters with functions that doesn't rely on introspection.
但更好的方法是简单地将参数与不依赖于内省的函数相关联。
#3
2
If you want to keep the foo
function with that exact same declaration and you don't mind each function receiving the whole set of parameters you could do it like this:
如果你想保持foo函数与完全相同的声明,你不介意每个函数接收整个参数集,你可以这样做:
You just need to add to each 'my_*'
function the **kwargs
parameter.
您只需要在每个'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 automatically parses kwargs
setting the b and c
parameters where it has the value.
Python自动解析kwargs设置它具有值的b和c参数。
#4
1
Another approach can be like this:
另一种方法可以是这样的:
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)
Output:
输出:
[[1, 2, 3], {'par_1': 'some_par'}]
[[1, 2, 3], {'par_2_0': 5, 'par_2_1': 11}]
I am sure that you can improvise your current code as it gets ugly in this way.
我确信您可以即兴创作当前的代码,因为它会以这种方式变得丑陋。
#5
1
I like @COLDSPEED's approach, but want to present yet another solution. Pass always 3 values: function, args, keyword args:
我喜欢@ COLDSPEED的方法,但想提出另一个解决方案。总是传递3个值:function,args,keyword args:
Usage:
用法:
foo(
func_1, ('some_par',), {},
func_2, (5, 11), {},
)
Implementation (Python3 syntax):
实现(Python3语法):
def foo(*args3):
while args3:
func, args, kwargs, *args3 = args3
func(*args, **kwargs)
#6
1
An approach would be making the 3rd argument of foo
a positional argument and pass in a list of args with functions list:
一种方法是使foo的第三个参数成为位置参数,并传入一个带有函数列表的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()
is used to map each function with the corresponding args.
zip()用于将每个函数与相应的args映射。
Output:
输出:
func1 called with {'par_1_1': 11, 'par_1_2': 12}
func2 called with {'par_2_1': 21, 'par_2_2': 22}
#7
1
You can do it something like that, "close" each parameters for function in a list item and then let "foo" split it backwards:
您可以这样做,“关闭”列表项中的函数的每个参数,然后让“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}])
#1
3
You could use the function's name as the keyword arguments. When indexing kwargs
, you'd use func_i.__name__
as the key.
您可以使用函数的名称作为关键字参数。索引kwargs时,你会使用func_i .__ name__作为键。
def foo(data, function_list, **kwargs):
for func_i in function_list:
print(func_i(data, kwargs[func_i.__name__]))
And now,
现在,
foo(data, [func_1, func_2], func_1='some_par', func_2=[5, 11])
#2
3
You could use inspect.getargspec
(I assume you use Python 2, you shouldn't use that function in Python 3 because it has been deprecated) to find out which argument names a function has and build a new dictionary based on those:
您可以使用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)
But a better way would be to simply associate parameters with functions that doesn't rely on introspection.
但更好的方法是简单地将参数与不依赖于内省的函数相关联。
#3
2
If you want to keep the foo
function with that exact same declaration and you don't mind each function receiving the whole set of parameters you could do it like this:
如果你想保持foo函数与完全相同的声明,你不介意每个函数接收整个参数集,你可以这样做:
You just need to add to each 'my_*'
function the **kwargs
parameter.
您只需要在每个'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 automatically parses kwargs
setting the b and c
parameters where it has the value.
Python自动解析kwargs设置它具有值的b和c参数。
#4
1
Another approach can be like this:
另一种方法可以是这样的:
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)
Output:
输出:
[[1, 2, 3], {'par_1': 'some_par'}]
[[1, 2, 3], {'par_2_0': 5, 'par_2_1': 11}]
I am sure that you can improvise your current code as it gets ugly in this way.
我确信您可以即兴创作当前的代码,因为它会以这种方式变得丑陋。
#5
1
I like @COLDSPEED's approach, but want to present yet another solution. Pass always 3 values: function, args, keyword args:
我喜欢@ COLDSPEED的方法,但想提出另一个解决方案。总是传递3个值:function,args,keyword args:
Usage:
用法:
foo(
func_1, ('some_par',), {},
func_2, (5, 11), {},
)
Implementation (Python3 syntax):
实现(Python3语法):
def foo(*args3):
while args3:
func, args, kwargs, *args3 = args3
func(*args, **kwargs)
#6
1
An approach would be making the 3rd argument of foo
a positional argument and pass in a list of args with functions list:
一种方法是使foo的第三个参数成为位置参数,并传入一个带有函数列表的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()
is used to map each function with the corresponding args.
zip()用于将每个函数与相应的args映射。
Output:
输出:
func1 called with {'par_1_1': 11, 'par_1_2': 12}
func2 called with {'par_2_1': 21, 'par_2_2': 22}
#7
1
You can do it something like that, "close" each parameters for function in a list item and then let "foo" split it backwards:
您可以这样做,“关闭”列表项中的函数的每个参数,然后让“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}])