2010-07-01 32 views
1

在下面的代码中,我打算有两个按钮,分别将'0'和'1'分别打印到标准输出时。然而,当程序运行时,它们都会打印出'1',这是我在迭代中的最后一个值。为什么?Python的lambda迭代不能按预期工作

import Tkinter as tk 
import sys 

root = tk.Tk() 

for i in range(0,2): 
    cmd = lambda: sys.stdout.write(str(i)) 
    tk.Button(text="print '%d'" % i,command=cmd).pack() 

root.mainloop() 

回答

5

i在您创建时不会捕获到lambda表达式中(如您所愿)。相反,这两个函数都会引用外部for循环中的i,该函数在创建函数之后以及运行之前发生更改。要捕捉它,你可以使用默认值:

for i in range(0,2): 
    cmd = lambda i=i: sys.stdout.write(str(i)) 
    tk.Button(text="print '%d'" % i,command=cmd).pack() 
3

当然它的问题

On lambdas, capture, and mutability

是一遍又一遍地来了......

+0

物品为不相关的蟒蛇 – newacct 2010-07-01 07:00:26

+1

它链接到Python的两个类似StackOverflow的问题,这个问题超越与Lambda和mutables大多数语言。 – Brian 2010-07-01 07:15:00

1

我觉得这是一个有点奇怪的是使用一个匿名函数然后给它一个名字。为什么不把它写成这样?

for i in 0,1: 
    def cmd(): 
     return sys.stdout.write(str(i)) 
    tk.Button(text="print '%d'"%i, command=cmd).pack() 
+1

@newacct:“for i in 0,1”是正确的语法。在交互式Python shell中尝试一下,看看会发生什么。 – Deestan 2010-07-01 08:56:54