在 Python 的 `for` 循环中定义函数时出现问题

Problem while defining a function in a `for` loop in Python

我有以下重现该问题的最小示例:

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() takes 1 positional argument but 2 were given

具有以下追溯:

---------------------------------------------------------------------------

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 完成,但我仍然不明白为什么上面的代码会这样工作。有什么提示吗?

您在定义 free-variable func 时关闭:

def _func(x):
    return func(*x)

但是,在你的循环中,你re-using这个名字,

for func in funcs:
    print(func([2, 3]))

所以 func 现在指的是您定义的 single-argument 函数,甚至在 _func 中!因此,当然,当该函数调用 func(*x) 时,它实际上是在递归调用自身。使用不同的名称:

for f in funcs:
    print(f([2, 3]))

或者更好的是,不要依赖 free-variable 你不想获得自由:

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

...