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

问题描述

我有以下最小的示例重现了这个问题:

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

...

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...