函数名不可重用(python)

函数名不可重用(python),python,functional-programming,Python,Functional Programming,我想创建函数并将它们添加到列表中,每次都重复使用相同的名称 def fconstruct(): flist = [] for x in xrange(0,5): def kol(): return x flist.append(kol) del kol #this doesn't fix the problem. return flist k = fconstruct() 然而,这失败了,即使我

我想创建函数并将它们添加到列表中,每次都重复使用相同的名称

def fconstruct():
    flist  = []
    for x in xrange(0,5):
        def kol():
            return x
        flist.append(kol)
        del kol #this doesn't fix the problem.
    return flist

k = fconstruct()
然而,这失败了,即使我每次循环都删除函数,而且无论我调用k中的哪个函数,结果都是一样的:4,因为kol的最新定义已经改变了以前所有的定义。对于这样一个简单的函数

kol = lambda: x 
会有用的。但是,我需要对一个更复杂的函数执行此操作

作为解决方案,我可以将函数作为字符串存储在列表中,并使用exec调用它

我可以生成一次性和随机函数名:

fname = '_'+str(random.random())
exec fname + ' = kol'
exec 'flist.append('+fname+')'
我可以使用多行lambda的这个实现:


所有这些看起来都不优雅,那么最好的方法是什么呢?

您必须使用另一个函数来生成所需的x参数集函数。在这里,我使用了kol_工厂的
(另请参见以下内容的答案):

您可以在
fconstruct
函数之外定义工厂函数factory:

def kol_factory(y):
    # y is local here
    def kol():
        # kol uses the y
        return y
    return kol

def fconstruct():
    flist  = []
    for x in xrange(0,5):
        # we create a new kol_factory with x "burned-in"
        flist.append(kol_factory(x))
    return flist

for k in  fconstruct():
   print k()

当您定义
kol
时,您正在围绕
x
建立一个闭包。事实上,每次通过循环,你都会得到一个关于同一个变量的闭包

因此,虽然您有5个不同的函数,都命名为
kol
,但它们都返回相同变量的值。循环完成后,该变量的值为4,因此每个函数返回4

考虑这一点:

def fconstruct():
    flist = []
    for x in range(5):
        def get_kol(y):
            def kol():
                return y
            return kol
        flist.append(get_kol(x))

    return flist
在本例中,函数
get_kol()
返回一个函数,该函数的返回值是
get_kol()
的参数

kol()
中的闭包现在大约是
y
,它是
get\u kol()
函数的局部闭包,而不是循环。每次调用
get_kol()
时,都会创建一个新的本地
y
,因此每个
kol()
都会获得一个不同的变量闭包


另一种方法是使用创建分部函数。这实现了同样的功能(创建一个函数,当调用该函数时,该函数将执行另一个带参数的函数),并且功能更加强大

def f(a): # whatever arguments you like
    return a

# create a bunch of functions that return f(x)
flist = [functools.partial(f, x) for x in range(5)]

def g(a, b): 
    return a + b

# create a bunch of functions that take a single argument (b), but have a set to
# 0..4: 
flist = [functools.partial(g, x) for x in range(5)] 

some_g = flist[0]
some_g(1) # returns 0 + 1

你想完成什么?似乎是一个XY问题。我想使用scipy.optimize.leastsq,它要求一个函数返回多个值(每个方程大概有一个值)。我将函数放入一个列表中,以便调用它们并分别返回值。既然您提到了它,我想我可以只存储值,而不是所有单独的函数。谢谢可能的重复与函数名和闭包无关。我会把
get_kol
放在循环之外,因为没有必要在每次迭代中创建一个新工厂。我很高兴你们加快了步伐,我没有时间去想它。
def f(a): # whatever arguments you like
    return a

# create a bunch of functions that return f(x)
flist = [functools.partial(f, x) for x in range(5)]

def g(a, b): 
    return a + b

# create a bunch of functions that take a single argument (b), but have a set to
# 0..4: 
flist = [functools.partial(g, x) for x in range(5)] 

some_g = flist[0]
some_g(1) # returns 0 + 1