我正在尝试在循环内创建函数:
functions = []
for i in range(3):
def f():
return i
# alternatively: f = lambda: i
functions.append(f)
问题在于所有功能最终都是相同的。所有三个函数都返回 2,而不是返回 0、1 和 2:
print([f() for f in functions])
# expected output: [0, 1, 2]
# actual output: [2, 2, 2]
为什么会发生这种情况,我应该怎样做才能获得分别输出 0、1 和 2 的 3 个不同函数?
最佳答案
您遇到了延迟绑定(bind)的问题 - 每个函数都会尽可能晚地查找i
(因此,当在循环结束后调用时, i
将设置为 2
)。
通过强制早期绑定(bind)轻松修复:将 def f():
更改为 def f(i=i):
,如下所示:
def f(i=i):
return i
默认值(i=i
中右侧的 i
是参数名称 i
的默认值,它是左侧的i=i
中的 hand i
)是在 def
时间查找的,而不是在 call
时间查找的,所以本质上它们是一种专门寻找早期绑定(bind)的方法。
如果您担心 f
获得额外的参数(因此可能被错误地调用),有一种更复杂的方法,其中涉及使用闭包作为“函数工厂”:
def make_f(i):
def f():
return i
return f
并在循环中使用 f = make_f(i)
而不是 def
语句。
关于python - 在循环(或推导式)中创建函数(或 lambda),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55871559/