在循环中创buildlambda

可能重复:
(lambda)函数闭包在Python中捕获什么?
lambda函数不closuresPython中的参数?

我正在尝试在迭代对象列表的循环内创buildlambdas:

lambdas_list = [] for obj in obj_list: lambdas_list.append(lambda : obj.some_var) 

现在,如果我遍历lambda表,并像这样调用它们:

 for f in lambdas_list: print f() 

我得到相同的价值。 这是obj_list最后一个obj的值,因为这是列表迭代器块中的最后一个variables。 对代码进行一个很好的(pythonic)重写以使其工作的任何想法?

改用这一行:

 lambdas_list.append(lambda obj=obj: obj.some_var) 

您必须使用默认分配捕获variables

 lambdas_list = [ lambda i=o: i.some_var for o in obj_list ] 

或者,使用闭包来捕获variables

 lambdas_list = [ (lambda a: lambda: a.some_var)(o) for o in obj_list ] 

在这两种情况下,关键是要确保obj_list列表中的每个值都分配给唯一的作用域。

您的解决scheme不起作用,因为词汇variablesobj是从父范围( for )引用的。

默认分配工作,因为我们从lambda范围引用i 。 我们使用默认的赋值来使隐含的variables成为lambda定义的一部分,并因此成为其范围。

闭包解决scheme工作,因为variables“通过”显式,到外部lambda立即执行,从而在列表理解期间创build绑定,并返回引用该绑定的内部lambda 。 所以当内部lambda实际执行时,它将引用在外部lambda范围内创build的绑定。

你可以这样做:

 def build_lambda(obj): return lambda : obj.some_var lambdas_list = [] for obj in obj_list: lambdas_list.append(build_lambda(obj))