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

ああ、スコーピング。これを行うとき:

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

あなたはその場で数に「解決」しているのではありませんその後、ラムダが呼び出されたときに参照するようにラムダに指示しているだけです。ii

forループの終わりi = 3(最後の値)を過ぎたときはいつでも、すべてのラムダは.3を要求したときに取得しますi

私が間違っていなければ、間接化の手段として関数を追加することができ、それはi周囲のスコープから適切に「キャプチャ」されます。

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