鉴于这段代码(python)
s = [None]*10
def func():
for i in range(10):
def update():
print i,
s[i] = update
func()
for i in range(10):
s[i]()
为什么这个结果是10个9,而不是0,1,2,3,... 9?
不过,我还打印了s [0] ~s [9],它们是10个函数地址,并且彼此不同。答案 0 :(得分:3)
您已在i
上创建了一堆闭包,但它们都共享i
的相同(最终)值
你需要做一个像这样的小修改
>>> s = [None]*10
>>> def func():
... for i in range(10):
... def update(i=i):
... print i,
... s[i] = update
...
>>> func()
>>> for i in range(10):
... s[i]()
...
0 1 2 3 4 5 6 7 8 9
答案 1 :(得分:0)
@ gnibbler的代码将修复你的(如果有人的话,接受他的回答)。至于打印全部9个的原因,请查看update
功能。你(再次提到@gnibbler)不断返回你在for i in range(10)
中定义的i。由于在原始代码中没有使用函数参数调用update
方法,因此它只打印i
范围中定义的func
(完全不同的i
在函数完成后将为9。)
为了使其更清晰,请尝试将i
中的func
更改为完全不同的名称 - 结果将是相同的。
答案 2 :(得分:0)
发生的事情与此相同:
>>> a = 5
>>> def foo(): print(a)
>>> foo()
5
>>> a = 10
>>> foo()
10
>>> a = 'fred'
>>> foo()
fred
也与此相同:
>>> def bar(): return b
>>> bar()
Traceback (most recent call last):
File "<pyshell#30>", line 1, in <module>
bar()
File "<pyshell#29>", line 1, in bar
def bar(): return b
NameError: global name 'b' is not defined
>>> b = 3
>>> bar()
3
在函数调用之前,函数内部使用的变量不会被解析,而不是写入。有一些神奇的,称为闭包,意味着在其他函数中定义的函数(因为update
函数在func
内定义)仍然可以访问外部定义的所有变量函数 - 但在函数调用之前,它们实际上仍然无法解析。因此,当您调用每个update
函数时,i
为9。
使用默认参数值,就像在@ gnibbler的答案中一样,因为每个i
查找的update
将解析为参数(隐藏外部变量)。那些不会改变,因为默认参数值是在定义函数时计算的(这也会导致许多人迟早遇到的mutable defaults bug)。