考虑到以下代码片段:
# directorys == {'login': <object at ...>, 'home': <object at ...>}
for d in directorys:
self.command["cd " + d] = (lambda : self.root.change_directory(d))我希望创建一个包含两个功能的字典,如下所示:
# Expected :
self.command == {
"cd login": lambda: self.root.change_directory("login"),
"cd home": lambda: self.root.change_directory("home")
}但是看起来,生成的两个lambda函数完全相同:
# Result :
self.command == {
"cd login": lambda: self.root.change_directory("login"),
"cd home": lambda: self.root.change_directory("login") # <- Why login ?
}我真的不明白为什么。你有什么建议吗?
发布于 2013-11-07 13:52:05
您需要为创建的每个函数绑定d。这样做的一种方法是将其作为具有默认值的参数传递:
lambda d=d: self.root.change_directory(d)现在,函数中的d使用该参数,尽管它具有相同的名称,并且在创建函数时将计算该参数的默认值。为了帮助你了解这个:
lambda bound_d=d: self.root.change_directory(bound_d)记住默认值是如何工作的,例如对于列表和dicts这样的可变对象,因为您正在绑定一个对象。
这种带有默认值的参数的习语很常见,但如果您内省函数参数并根据它们的存在来确定该做什么,则可能会失败。您可以使用另一个闭包来避免参数:
(lambda d=d: lambda: self.root.change_directory(d))()
# or
(lambda d: lambda: self.root.change_directory(d))(d)发布于 2013-11-07 13:47:35
这是由于d被约束的点。lambda函数都指向变量d,而不是它的当前值,因此,当您在下一次迭代中更新d时,所有函数都会看到此更新。
更简单的例子是:
funcs = []
for x in [1,2,3]:
funcs.append(lambda: x)
for f in funcs:
print f()
# output:
3
3
3您可以通过添加一个额外的函数来解决这个问题,如下所示:
def makeFunc(x):
return lambda: x
funcs = []
for x in [1,2,3]:
funcs.append(makeFunc(x))
for f in funcs:
print f()
# output:
1
2
3还可以修复lambda表达式中的作用域。
lambda bound_x=x: bound_x但是,一般来说,这是,而不是良好实践,因为您已经更改了函数的签名。
发布于 2019-07-31 10:03:08
或者,您可以使用lambda代替functools.partial,在我看来,它具有更清晰的语法。
而不是:
for d in directorys:
self.command["cd " + d] = (lambda d=d: self.root.change_directory(d))它将是:
for d in directorys:
self.command["cd " + d] = partial(self.root.change_directory, d)或者,下面是另一个简单的例子:
numbers = [1, 2, 3]
lambdas = [lambda: print(number)
for number in numbers]
lambdas_with_binding = [lambda number=number: print(number)
for number in numbers]
partials = [partial(print, number)
for number in numbers]
for function in lambdas:
function()
# 3 3 3
for function in lambdas_with_binding:
function()
# 1 2 3
for function in partials:
function()
# 1 2 3https://stackoverflow.com/questions/19837486
复制相似问题