在循环中创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))