概要
ご無沙汰しております。うらさくと申します
この記事はTechCommit Advent Calendar 2023の5日目の記事です
3年連続のアドカレです
今回はPythonのtkinterでボタンにlambda式関数をバインドするときに躓いたので、備忘録として共有します
修正前コード
buttons = [tkinter.Button(root, text="テスト", command=lambda: self.test_function(True, i)) for i in range(5)]
こんな感じでtkinterのボタンコンポーネントをfor文で5つ作る際、そのボタンのインデックス(0~4)を押したときに発火する関数の引数に入れたいというケースがありました
起こった事象
このコードを組み込んだプログラムを実行してそのボタンを押してみると、すべてのボタンでindexの引数に4、つまり、ループの最後の値が反映されていました
原因は、変数名はforループの各繰り返しで再代入されるという仕様でした
解決策
lambda式内でデフォルトのキーワードパラメータを使用することで解決できます
buttons = [tkinter.Button(root, text="テスト", command=lambda index=i: self.test_function(True, i)) for i in range(5)]
まとめ
tkinterに限らず、for文×lambdaの組み合わせはPythonではたまにあると思うので、同じところで詰まっている方は参考にしていただけると幸いです
参考