我正在尝试生成一些依赖于变量的函数f
并将它们存储在列表fs
中。
我第一次尝试
fs = []
for v in range(3):
def f():
print(v)
fs.append(f)
for f in fs:
f()
但是这个输出
2
2
2
即只有最后一个函数被调用。
我认为可能是因为函数f
在每次循环时都会被覆盖,但是后来我尝试了
fs = []
for v in range(3):
def f():
print(v)
fs.append(f)
def f():
print('foo')
fs.append(f)
for f in fs:
f()
输出
2
foo
2
foo
2
foo
因此python似乎至少能够区分具有相同名称的这两个函数。
那我虽然会动态创建f
:
fs = []
for v in range(3):
def make_f():
def f():
print(v)
return f
fs.append(make_f())
for f in fs:
f()
但仍会输出
2
2
2
最后,我参数化了make_v
工厂,并最终获得了想要的结果:
fs = []
for v in range(3):
def make_f(v):
def f():
print(v)
return f
fs.append(make_f(v))
for f in fs:
f()
打印
0
1
2
即使我最终通过一种解决方案破解了自己的方法,但我认为我绝对对python在这种情况下如何捕获变量或函数缺乏深入的了解。有人可以解释这种行为背后的原因吗?还有一种更直接的方法来实现我最初想要做的事情吗?
答案 0 :(得分:-1)
问题在于变量绑定,因为它们在全局范围内引用了v
,最后以2结尾。您可以通过将变量绑定到本地范围来解决此问题。
fs = []
for v in range(3):
def make_f(v=v):
def f():
print(v)
return f
fs.append(make_f())
for f in fs:
f()
希望这有助于进一步了解发生的事情。