web-dev-qa-db-ja.com

ラムダとのループ内のTkinter割り当てボタンコマンド

私は次のようないくつかのボタン(for付き)を作成しようとしています:

def a(self, name):
    print name

users = {"Test":"127.0.0.0", "Test2":"128.0.0.0"}
row = 1
for name in users:
    user_button = Tkinter.Button(self.root,
                                 text=name,
                                 command=lambda: self.a(name))
    user_button.grid(row = row, column = 0)
    row+=1

ボタンはそれぞれ独自のパラメーターを取得します(TestはTestを取得し、Test2はTest2を取得します)が、ボタンを押すと、両方とも「Test2」と出力されます。これは、同じパラメーターで同じ関数を使用していることを意味します。

どうすればこれを解決できますか?

28
Shay

問題は、forループ内のランバです。ラムダはname変数を使用していますが、name変数はforループを介して毎回再割り当てされます。したがって、最終的に、すべてのボタンは、forループでnameが割り当てられた最後の値を取得します。これを回避するには、次のように、ランバ式でデフォルトのキーワードパラメータを使用できます。

user_button = Tkinter.Button(self.root,
                             text=name,
                             command=lambda name=name: self.a(name))

これにより、ループを通過するたびに、name変数の現在の値がランバのnameキーワード引数にバインドされ、目的の効果が得られます。

38
mshildt