0

我已经定义了一个类,它采用 [fname1,[parameters1],fname2,[parameters2],...] 形式的列表作为创建实例的参数。

这个想法是让实例一次执行列表中的所有函数,将它们各自的参数传递给它们——这工作得很好,但我想出的实现非常难看。它看起来像这样:

# (The input list is split up and transformed into two lists -
# one containing the function names as strings, the other one containing tuples)
# (It then runs a for-loop containing the following statement)

exec '%s%s'%(fname[i],repr(parameter_tuple[i]))

哪个输出并运行'fname(parameters,more_parameters,and,so,on)',就像它应该做的那样。

我不知道为什么,但是自从我编写了这个代码后,我因此认为我应该为此受到一次非常好的打击......虽然它有效,但我只知道必须有一个不那么丑陋的实现。有谁愿意帮我看看吗?或者也许是为了打败我?;-)

4

2 回答 2

4

如果可以的话,这里最简单的答案是简单地传递函数而不是函数名,然后做一个简单的:

for function, params in zip(functions, parameters):
    function(*params)

请注意我使用zip()来一​​次循环两个列表。这是比循环索引更 Pythonic 的选项。

或者,或者,使用itertools.starmap().

如果你真的不能直接传递函数,那就更难了。一方面,任何依赖变量名称的解决方案本质上都是脆弱的,因此最好的选择是创建一个从函数名称到函数的显式字典,然后查找函数。

否则,我建议使用该inspect模块来查找您想要的功能。例如:

import inspect
import sys

def some_function():
       ...

print(dict(inspect.getmembers(sys.modules[__name__], inspect.isfunction)))

产生:

{'some_function': <function some_function at 0x7faec13005a0>}

但是请注意,这种方法的效率要低得多,而且更加迂回。最好的答案仍然是传递函数本身。

于 2012-09-22T10:59:57.500 回答
0

这是一个函数,它接受一个函数列表(不是函数名)和一个参数列表(或元组):

def callmany(funs, funargs):
    return [f(*args) for (f,args) in zip(funs, funargs)]

它返回一个结果列表,其中结果中的第一个元素是使用 funargs 中的第一个参数列表调用 funs 中的第一个函数的结果。像这样:

callmany([len, range], [["hello"], [1, 10]])
>> [5, [1, 2, 3, 4, 5, 6, 7, 8, 9]]
于 2012-09-22T11:04:52.567 回答