2

我正在尝试使用 Tkinter 制作计算器。我一直在尝试清理代码,但遇到了障碍。创建按钮时,我使用以下代码:

Button(self,text="1",command=lambda: self.addkey("1"),width=self.defaultwidth,height=self.defaultheight).grid(row=5, column=0)
Button(self,text="2",command=lambda: self.addkey("2"),width=self.defaultwidth,height=self.defaultheight).grid(row=5, column=1)
Button(self,text="3",command=lambda: self.addkey("3"),width=self.defaultwidth,height=self.defaultheight).grid(row=5, column=2)

以下是调用的命令

def addkey(self,key):
            # Adds a given key to the display
            if len(self.displaytext) + len(key) <= self.maxlength:
                self.displaytext += key
                self.display["text"] = self.displaytext

当按顺序按下按钮 1、2 和 3 时,输出如下:

123

我一直在尝试清理代码,使其看起来更像:

for i in range(3):
    Button(self,text=str(i+1),command=lambda: self.addkey(str(i+1)),width=self.defaultwidth,height=self.defaultheight).grid(row=5, column=i)

这很好地添加了按钮,但是当按顺序按下 1、2 和 3 时,屏幕上会显示以下内容:

333

我想知道我是否错过了什么,或者这根本不可能。

4

1 回答 1

5

Ah, scoping. When you do this:

command=lambda: self.addkey(str(i))

You're not "resolving" the i to a number right there and then. You're just telling the lambda to reference i when it's invoked, afterwards.

At any time past the end of the for loop, i = 3 (last value), so all of your lambdas get 3 when they ask for i.

If I'm not mistaken, you can add a function as means of indirection, and it will appropriately "capture" i from the surrounding scope.

def add_key_f(i):
    return lambda self: self.addkey(i)
于 2013-03-08T23:42:09.770 回答