我一遍又一遍地重复以下代码:
def foo(data):
result = (0, 0, 0)
var1, var2, var3 = init_variables(data)
for i in xrange(var1):
result[0] += variable_func_1(data, var2, var3)
result[1] += variable_func_2(data, var3)
result[2] += fixed_func()
return result
在所有重复中,一切都是固定的,除了variable_func_n
可以采用可变数量的参数,这些函数的数量也各不相同。
我想在所有这些函数中分解公共代码,因此首先想到的是使用更高阶函数,如下所示:
def foo(data, func_list):
var1, var2, var3 = init_variables(data)
results = (len(func_list) + 1) * [0]
for i in xrange(var1):
for j, func in enumerate(func_list):
results[j] += (func(data, var1, var2, var3))
results[len(func_list)] += fixed_func()
return results
这个解决方案的问题在于它要求我修改所有变化函数的签名,以便它们可以获取更多参数。是否有一个更清洁的解决方案,不需要我修改所有传入函数的签名?
答案 0 :(得分:1)
也许您正在寻找inspect
模块?
In [11]: import inspect
In [12]: def f(a, b): pass
In [13]: inspect.getargspec(f)
Out[13]: ArgSpec(args=['a', 'b'], varargs=None, keywords=None, defaults=None)
这个库可以告诉你每个函数中的参数数量,以及每个参数的名称,这样你就可以添加自己的逻辑来确保正确调用函数。
真正的答案是你可能需要重构你的代码,说实话这个模式对我来说有点奇怪..
答案 1 :(得分:0)
我认为最简单的方法是简单地传递包含所有数据的List。
您也可以为每个函数提供可选参数,但这无济于事
答案 2 :(得分:0)
假设您的函数数量有限,那么创建参数查找表怎么样?它确实插入了一个额外的重定向层并复制了一些信息,但如果我理解正确的话,它会再次替换很多其他的复制函数:
func_sigs = {
func1: ['data', 'var2', 'var3'],
func2: ['data', 'var3']
}
def call_func(f, data, var1, var2, var3):
args = [locals()[key] for key in func_sigs[f]]
return f(*args)
def foo(data, func_list):
var1, var2, var3 = init_variables(data)
results = (len(func_list) + 1) * [0]
for i in xrange(var1):
for j, func in enumerate(func_list):
results[j] += (call_func(func, data, var1, var2, var3))
results[len(func_list)] += fixed_func()
return results
更大的问题是为什么你要保持签名的原样:你保持API兼容性还是只是不想重构?