Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Mengendalikan Isu Skop Pembolehubah dalam Penutupan Lambda Tidak Bersarang?

Bagaimana untuk Mengendalikan Isu Skop Pembolehubah dalam Penutupan Lambda Tidak Bersarang?

Barbara Streisand
Barbara Streisandasal
2024-10-21 13:10:03683semak imbas

How to Handle Variable Scoping Issues in Non-Nested Lambda Closures?

Skop Penutupan Python Lambda

Masalah

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.

Jawapan

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.

Alternatif dengan Lambda Berbalut

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.

Kesimpulan

Pemahaman dan mengurus skop pembolehubah dalam penutupan adalah penting untuk reka bentuk kod dan penyahpepijatan yang berkesan. Perkara utama ialah:

  • Penutupan memegang nama pembolehubah, bukan nilai
  • Penilaian pembolehubah berlaku semasa pelaksanaan lambda
  • Untuk menangkap pembolehubah, sama ada hantarkannya sebagai argumen atau bungkus lambda dalam fungsi lain

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn