Pertimbangkan coretan kod berikut:
# directorys == {'login': <object at ...>, 'home': <object at ...>} for d in directorys: self.command["cd " + d] = (lambda : self.root.change_directory(d))
Matlamatnya ialah untuk mencipta kamus dua fungsi dengan kunci " cd login" dan "cd home". Walau bagaimanapun, keputusan menunjukkan bahawa kedua-dua fungsi lambda mempunyai kandungan yang sama dengan kunci "log masuk cd".
Untuk memahami tingkah laku yang tidak dijangka ini, adalah penting untuk mempertimbangkan cara fungsi lambda berfungsi dalam gelung bersarang. Apabila fungsi lambda ditakrifkan dalam gelung, ia menangkap pembolehubah daripada skop sekeliling. Dalam kes ini, pembolehubah d daripada gelung ditangkap oleh setiap fungsi lambda.
Walau bagaimanapun, fungsi lambda dilaksanakan secara malas. Jadi, apabila anda mengakses kamus self.command di luar gelung, semua fungsi lambda telah menangkap pembolehubah d yang sama, iaitu nilai terakhir d dalam gelung. Oleh itu, semua fungsi menunjuk kepada kaedah yang sama, menghasilkan tingkah laku yang diperhatikan.
Untuk menyelesaikan isu ini, kita perlu memastikan bahawa setiap fungsi lambda menangkap nilai d yang berbeza. Satu penyelesaian ialah dengan menghantar d sebagai parameter kepada fungsi lambda dan memberikan nilai lalai:
lambda d=d: self.root.change_directory(d)
Kini, d dalam fungsi lambda menggunakan parameter, walaupun ia mempunyai nama yang sama. Nilai lalai untuk parameter ini dinilai apabila fungsi dicipta, mengikatnya pada nilai d yang betul untuk setiap lelaran gelung.
Sebagai alternatif, kita boleh menggunakan penutupan bersarang untuk mencapai hasil yang sama:
(lambda d: lambda: self.root.change_directory(d))(d)
Atas ialah kandungan terperinci Mengapa Lambda Berfungsi dalam Gelung Menangkap Nilai Terakhir Daripada Setiap Nilai Lelaran?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!