Python的lambda迭代未按预期工作

1 投票
3 回答
505 浏览
提问于 2025-04-16 00:39

在下面的代码中,我想要有两个按钮,当每个按钮被按下时,分别打印'0'和'1'到标准输出。但是当程序运行时,它们都打印'1',这是我在循环中最后一个值。为什么会这样呢?

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()

3 个回答

1

我觉得用一个匿名函数然后再给它起个名字有点奇怪。为什么不直接这样写呢?

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

当然,这个问题出现在

关于闭包、捕获和可变性

的内容中,反复出现...

5

在你创建这个 lambda 函数的时候,i 并没有被捕获(也就是你想要的那样)。相反,这两个函数都指向外部 for 循环里的 i,而这个 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()

撰写回答