我的问题是如何与this question相关,我有一个函数字典,其中有不同数量的参数,我怎么能以自动方式调用它们?
funcdict = {
'mypackage.mymodule1.myfunction1': mypackage.mymodule.myfunction,
'mypackage.mymodule2.myfunction2': mypackage.mymodul2.myfunctio2,
....
}
funcdict[0](parameter1, parameter2)
funcdict[1](parameter1, parameter2, parameter3)
funcdict[1](parameter1, parameter2, parameter3,parameter4,parameter5)
.........
而不是像上面那样调用他们中的每一个想要像这样的东西
for i in range(len(funcdict)):
funcdict[i](......)
不知道我应该如何填充参数,因为每个函数的参数数量在2到6之间变化。
答案 0 :(得分:2)
如果您想以自动方式调用所有功能,特别是一次性调用所有功能,那么您可以通过某些特定名称(例如您引用的问题中)调用它们并不重要。您可以将这些功能保留在列表中并依次调用每个功能。
至于处理可变数量的参数,Python有一个你在一些方法声明中看到的“splat”运算符:def __init__(self, *args, **kwargs)
。此运算符可用于解压缩参数列表。 (有关详细信息,请参阅this SO answer)
如果将参数存储在另一个列表中,您可以遍历您的函数列表,并使用相同的语法逐个将参数应用于其相应的函数,而不指定参数的数量:
funclist = [lambda x,y: x+y, lambda x,y,z: x+y+z, lambda x: -x]
paramlist = [(1,2), (1,2,3), (1,)]
for index, func in enumerate(funclist):
print func(*paramlist[index])
如何将函数链接到默认参数是另一回事:您可以将它们保存在两个列表中,或者将它们作为另一个列表或字典中的元组保存在一起,或者定义一个轻量级类来保存它们......这取决于您的问题。无论如何,听起来对你来说重要的部分是*
符号。
修改强>
如果要将关键字参数传递给函数,可以使用double- *表示法传递字典并将其扩展为所需的关键字参数:
def func1(n_samples, noise, factor, random_state):
print locals()
def func2(n_samples, ratio, noise):
print locals()
def func3(my_key, default_key='world!'):
print locals()
funclist = [func1, func2, func3]
paramlist = [
dict(
n_samples=1000,
noise=0.3,
factor=0.5,
random_state=1
),
dict(
n_samples=1000,
ratio=0.5,
noise=0.1
),
dict(
my_key='hello',
)
]
for index, func in enumerate(funclist):
func(**paramlist[index])
答案 1 :(得分:1)
好的,我们假设您将参数放在元组中。您还需要优化表,以便了解每个函数需要多少个参数,这意味着修改数据结构(您可以使用inspect
模块来确定这一点,但这是目前不必要的复杂因素:
如果函数必须被调用任何特定的顺序,顺便说一下,dict不是一个好的结构,因为它以不可预测的顺序线性化,但我们现在忽略了。这是一段代码,使用*表示法将元组作为单独的参数传递。我正在使用记者功能来证明你有参数传输工作。
parameters = ("one", "two", "three", "four", "five")
def reporter(*args):
print("Called with", len(args), "arguments")
print("args are:", args)
funcdict = {
'mypackage.mymodule1.myfunction1': (reporter, 1),
'mypackage.mymodule2.myfunction2': (reporter, 5),
}
for name, (function, arg_ct) in funcdict.items():
print("Testing", name)
function(*parameters[:arg_ct])
输出结果为:
Testing mypackage.mymodule1.myfunction1
Called with 1 arguments
args are: ('one',)
Testing mypackage.mymodule2.myfunction2
Called with 5 arguments
args are: ('one', 'two', 'three', 'four', 'five')
我希望能为你提供足够的东西。
答案 2 :(得分:0)
作为第一种可能性,可以通过获取func_code
属性然后查询此代码对象的co_argcount
来尝试使用函数的代码对象。
这是一个小例子,它通过名称调用存储在字典中的函数,对于一组输入参数,在这种情况下为2, 3, 4
:
#!/usr/bin/env python
def f1(a, b):
print "executing f1 with %d, %d" % (a, b)
return a*b
def f2(a, b, c):
print "executing f2 with %d, %d, %d" % (a, b, c)
return a*b+c
def call_functions(arg1, arg2, arg3):
funcdict = {
"add" : f1,
"madd" : f2
}
for f in funcdict.itervalues():
if f.func_code.co_argcount == 2:
f(arg1, arg2)
elif f.func_code.co_argcount == 3:
f(arg1, arg2, arg3)
# and so on
if __name__=="__main__":
call_functions(2, 3, 4)
另一种稍微冗长的可能性(你不需要明确地检查每个函数的参数数量,函数只是使用他们需要的函数)就是使用Python的变量参数语法。这看起来如下:
#!/usr/bin/env python
def f1(*args):
print "executing f1 with %d, %d" % (args[0], args[1])
return args[0]*args[1]
def f2(*args):
print "executing f2 with %d, %d, %d" % (args[0], args[1], args[2])
return args[0]*args[1]+args[2]
def call_functions(*args):
funcdict = {
"add" : f1,
"madd" : f2
}
for f in funcdict.itervalues():
f(*args)
if __name__=="__main__":
call_functions(2, 3, 4)