关于以下代码的运行结果(Python,少于10行)

时间:2012-08-15 05:34:35

标签: python

鉴于这段代码(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个函数地址,并且彼此不同。

3 个答案:

答案 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)。