Rumah > pembangunan bahagian belakang > Tutorial Python > Analisis skop penutupan dan lambda dalam Python

Analisis skop penutupan dan lambda dalam Python

WBOY
Lepaskan: 2022-07-22 19:53:30
ke hadapan
2617 orang telah melayarinya

Artikel ini membawakan anda pengetahuan yang berkaitan tentang Python terutamanya mengatur isu berkaitan tentang skop lambda, serta kandungan yang berkaitan tentang penutupan dalam Python membantu semua orang.

Analisis skop penutupan dan lambda dalam Python

[Cadangan berkaitan: Tutorial video Python3 ]

Skop penutupan Python dan lambda

Kaedah Penulisan lambda

def fun():
    for i in range(3):
        yield lambda x : x * i

f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))
Salin selepas log masuk

Kaedah penulisan penutup

def fun():
    result = []
    for i in range(3):
        def demo(x):
            return x * i
        result.append(demo)
    return result
f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))
Salin selepas log masuk

Hasil kedua-dua kaedah penulisan di atas ialah 2, 4, 6. Mengikut idea asal, hasilnya hendaklah 0, 2, 6.

Punca masalah:

Masalahnya terletak pada peraturan carian pembolehubah python, LEGB (tempatan, tertutup, global, bulitin dalam contoh di atas, i ialah dalam skop Penutupan (melampirkan), dan penutupan Python adalah terikat lewat Nilai pembolehubah yang saya gunakan dalam penutupan ditemui apabila fungsi dalaman dipanggil.

Penyelesaian

Tukar skop penutupan kepada skop setempat

kaedah penulisan lambda

def fun():
    for i in range(3):
        yield lambda x, i = i: x * i

f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))
Salin selepas log masuk

kaedah penulisan penutupan

def fun():
    result = []
    for i in range(3):
        def demo(x, i=i):
            return x * i
        result.append(demo)
    return result
f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))
Salin selepas log masuk

Hasil keluaran di atas ialah 0, 2, 6

Situasi lain:

def fun():
    for i in range(3):
        yield lambda x : x * i
f0, f1, f2 = fun()
print(f0(1), f1(2), f2(3))
Salin selepas log masuk

Hasil keluaran masih 2, 4, 6

Punca masalah

Penjana (atau iterator) yang dikembalikan oleh kaedah fun() sebenarnya tidak dilaksanakan, tetapi dilaksanakan setiap kali ia dipanggil.

Apabila pencetakan dilakukan selepas traversal, pembolehubah i menggunakan nilai panggilan terakhir. Jika lambda dianggap sebagai kaedah penutupan, nilai pembolehubah i masih dalam skop penutupan (tiada setempat)

Perangkap dalam python (penutupan dan lambda)

Mari kita lihat buah berangan pertama

def create():
    return [lambda x:i*x for i in range(5)]
 
for i in create():
    print(i(2))
Salin selepas log masuk

Keputusan:

8

8

8

8

8

Nilai pulangan bagi fungsi cipta ialah senarai, dan setiap elemen senarai ialah fungsi - fungsi yang mendarabkan parameter input x dengan berbilang i. Keputusan yang dijangkakan ialah 0, 2, 4, 6, 8. Tetapi keputusannya ialah 5 dan 8, yang tidak dijangka.

Memandangkan lambda sering digunakan apabila perangkap ini berlaku, anda mungkin fikir ia adalah masalah dengan lambda, tetapi lambda menyatakan keengganannya untuk disalahkan. Intipati masalah terletak pada peraturan carian atribut dalam python, LEGB (local, enclosing, global, bulitin Dalam contoh di atas, i berada dalam skop penutupan (melampirkan), dan penutupan Python adalah pengikatan lewat nilai pembolehubah yang digunakan dalam penutupan ditanya apabila fungsi dalaman dipanggil

Penyelesaiannya juga sangat mudah, iaitu menukar skop penutupan kepada skop setempat.

def create():
    return [lambda x, i=i:i*x for i in range(5)]
 
for i in create():
    print(i(2))
Salin selepas log masuk

Cara penulisan lain:

def create():
    a = []
    for i in range(5):
        def demo(x, i=i):
            return x*i
        a.append(demo)
    return a
 
for i in create():
    print(i(2))
Salin selepas log masuk

Dua cara penulisan di atas adalah sama

Hasilnya:

0
2
4
6
8

Satu lagi buah berangan dengan masalah yang sama

Kodnya sangat mudah: (Penafian: masalah python3)

nums = range(2,20)
for i in nums:
    nums = filter(lambda x: x==i or x%i, nums)
print(list(nums))
Salin selepas log masuk

Keputusan:

[2, 3, 4, 5, 6, 7, 8, 9, 10 , 11, 12, 13 , 14, 15, 16, 17, 18, 19]

Begitu juga mengikut logik biasa, hasilnya hendaklah:

[2 , 3, 5, 7, 11 , 13, 17, 19]

Punca masalah:

  • Dalam python3, penapis( ) fungsi mengembalikan iterator. Oleh itu, ia sebenarnya tidak dilaksanakan, tetapi dilaksanakan setiap kali ia dipanggil (senarai nilai yang dikembalikan oleh filter() dalam python2 tidak mempunyai fenomena ini)
  • Apabila pencetakan dilaksanakan selepas traversal , gelung kini dilaksanakan Fungsi, masalah yang sama seperti berangan di atas Pembolehubah i menggunakan nilai apabila ia dipanggil kali terakhir Berangan di atas adalah berangan di atas menggunakan nilai skop terbenam, dan berangan ini menggunakan nilai global i

Kod diubah suai:

nums = range(2,20)
for i in nums:
    nums = filter(lambda x,i=i: x==i or x%i, nums)
print(list(nums))
Salin selepas log masuk

Keputusan:

[2, 3, 5, 7, 11, 13, 17, 19]

[Pengesyoran berkaitan: Tutorial video Python3]

Atas ialah kandungan terperinci Analisis skop penutupan dan lambda dalam Python. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:jb51.net
Kenyataan Laman Web ini
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
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan