Rumah > Artikel > pembangunan bahagian belakang > Bagaimana untuk Mengendalikan Isu Skop Pembolehubah dalam Penutupan Lambda Tidak Bersarang?
Merangkum pembolehubah dalam penutupan untuk mengeluarkannya daripada tandatangan fungsi ialah teknik yang sering digunakan untuk penstrukturan kod yang cekap. Walau bagaimanapun, dalam kes lambda tidak bersarang, penutupan mengekalkan nilai akhir pembolehubah, yang membawa kepada isu apabila cuba mengakses nilai tertentu berdasarkan pembolehubah lelaran.
Pertimbangkan coretan kod yang disediakan:
names = ['a', 'b', 'c'] def test_fun(name, x): print(name, x) def gen_clousure(name): return lambda x: test_fun(name, x) funcs1 = [gen_clousure(n) for n in names] funcs2 = [lambda x: test_fun(n, x) for n in names] # Expected output for funcs1 for f in funcs1: f(1) # Unexpected output for funcs2 (returns last element for all cases) for f in funcs2: f(1)
Memahami sebab di sebalik percanggahan ini adalah penting untuk penggunaan penutupan yang berkesan.
Konsep asas dalam situasi ini ialah skop pembolehubah dalam penutupan . Penutupan sememangnya memegang nama pembolehubah dan bukannya nilainya. Ini bermakna penilaian pembolehubah berlaku apabila pelaksanaan lambda dimulakan, bukannya pada masa definisi lambda.
Dalam kes funcs2, apabila anda melaksanakan lambda x: test_fun(n, x), pembolehubah n tidak dinilai semasa definisi lambda. Sebaliknya, penilaian hanya berlaku apabila panggilan lambda. Pada ketika itu, n memegang nilai terakhir dari gelung (iaitu 'c' dalam contoh ini). Akibatnya, fungsi f sentiasa menggunakan 'c' sebagai nilai n, tanpa mengira input x.
Untuk menangani isu ini dan mencapai kefungsian yang diingini, pembolehubah n mesti ditangkap dalam skop fungsi lambda. Ini boleh dicapai dengan melalukan pembolehubah sebagai hujah kepada lambda, seperti yang ditunjukkan dalam perkara berikut:
funcs2 = [lambda x: test_fun(n, x) for n in names if 2 > 0]
Dengan memasukkan pernyataan-jika tambahan ini yang sentiasa benar, kami memaksa lambda untuk mengambil nilai n sebagai hujah, memastikan gelagat diperibadikan yang dijangkakan merentas semua kes.
Sebagai alternatif, anda boleh membungkus lambda tidak bersarang dalam bersarang berfungsi, menghalang akses kepada pembolehubah tidak diisytiharkan dalam skop dengan berkesan. Kod berikut menggambarkan pendekatan ini:
def makeFunc(n): return lambda x: x+n stuff = [makeFunc(n) for n in [1, 2, 3]] for f in stuff: print(f(1))
Di sini, pembolehubah n ditangkap dalam fungsi makeFunc, memastikan skop yang betul dalam lambda.
Pemahaman dan mengurus skop pembolehubah dalam penutupan adalah penting untuk reka bentuk kod dan penyahpepijatan yang berkesan. Perkara utama ialah:
Atas ialah kandungan terperinci Bagaimana untuk Mengendalikan Isu Skop Pembolehubah dalam Penutupan Lambda Tidak Bersarang?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!