问题描述
我有以下最小的示例重现了这个问题:
def f1(a,b):
print(1)
return a + b
def f2(a,b):
print(2)
return a * b
funcs = f1,f2
_funcs = []
for func in funcs:
def _func(x):
return func(*x)
_func.__name__ = func.__name__
_funcs.append(_func)
funcs = _funcs
for func in funcs:
print(func([2,3]))
这会引发TypeErro
:
TypeError:_func()接受1个位置参数,但给出了2个
具有以下追溯:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-93-e24e67b5e525> in <module>()
22
23 for func in funcs:
---> 24 print(func([2,3]))
<ipython-input-93-e24e67b5e525> in _func(x)
14
15 def _func(x):
---> 16 return func(*x)
17
18 _func.__name__ = func.__name__
TypeError: _func() takes 1 positional argument but 2 were given
我不确定为什么_func()
总是用单个参数调用。
我怀疑我想用functools
来完成什么,但是我仍然看不到为什么上面的代码如此工作。有提示吗?
解决方法
定义以下内容时,您正在关闭自由变量func
:
def _func(x):
return func(*x)
但是,在循环中,您重复使用了这个名称,
for func in funcs:
print(func([2,3]))
所以func
现在引用了您定义的单参数函数,甚至在_func
内部!因此,当然,当该函数调用func(*x)
时,它实际上是在递归地调用自身。使用其他名称:
for f in funcs:
print(f([2,3]))
或者更好的是,不要依赖您不打算自由的自由变量:
def func_maker(func):
def _func(x):
return func(*x)
return _func
并使用它:
...
_funcs = []
for func in funcs:
_func = func_maker(func)
_func.__name__ = func.__name__
_funcs.append(_func)
funcs = _funcs
...