Python中的函数对象

3

我想创建一个函数列表,由固定基础函数创建的函数对象组成,但输入参数不同。我已经编写了以下代码:

def f_base(name):
    print "I am %s" % name

f_list = []
for name in ['A', 'B']:
    f_list.append(
        lambda : f_base(name)
    )

f_list[0]()
f_list[1]()

结果是:

I am B
I am B

但我想获得:

I am A
I am B

有人能解释一下为什么Python会产生这样的输出,以及获取我需要的结果的最简单方法是什么吗?
2个回答

4
现在使用的所有lambda函数只是在主体中调用name变量上的f_base。name变量是在调用这些lambda函数时确定的,而不是在创建每个函数时确定。
在循环结束后,变量name指向B,因为Python会在循环完成后保留在for循环中定义的变量。
如果你执行以下操作,这一点尤其明显:
name = 'C'

循环后,在调用函数之前。然后您会得到:
I am C
I am C

为了实现您想要的功能,您需要创建一个闭包函数或者更好的选择是使用functools.partial
import functools

def f_base(name):
    print "I am %s" % name

f_list = []
for name in ['A', 'B']:
    f_list.append(
        functools.partial(f_base, name)
    )

f_list[0]()
f_list[1]()

这将产生,

I am A
I am B

也被称为臭名昭著的“晚期绑定陷阱 - bereal
太好了!感谢你的回答! - Fomalhaut

1
你可以创建闭包:
def f_base(name):
    def closure():
        print "I am %s" % name
    return closure

f_list = []
for name in ['A', 'B']:
    f_list.append( f_base(name) )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接