Penutupan Python: Bagaimana menggunakannya dan Mengapa?

Dalam tutorial ini, anda akan belajar mengenai penutupan Python, cara menentukan penutupan, dan sebab-sebab anda harus menggunakannya.

Pemboleh ubah tidak tempatan dalam fungsi bersarang

Sebelum mengetahui apa itu penutupan, kita harus terlebih dahulu memahami apa itu fungsi bersarang dan pemboleh ubah bukan lokal.

Fungsi yang ditentukan dalam fungsi lain disebut fungsi bersarang. Fungsi bersarang dapat mengakses pemboleh ubah dari ruang lingkup.

Di Python, pemboleh ubah bukan tempatan ini hanya boleh dibaca secara lalai dan kami mesti menyatakannya secara eksplisit sebagai bukan tempatan (menggunakan kata kunci bukan tempatan) untuk mengubahnya.

Berikut adalah contoh fungsi bersarang mengakses pemboleh ubah bukan tempatan.

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) printer() # We execute the function # Output: Hello print_msg("Hello")

Pengeluaran

 Helo

Kita dapat melihat bahawa printer()fungsi bersarang dapat mengakses pemboleh ubah msg bukan lokal dari fungsi melampirkan.

Mendefinisikan Fungsi Penutupan

Dalam contoh di atas, apa yang akan berlaku sekiranya baris terakhir fungsi print_msg()mengembalikan printer()fungsi daripada memanggilnya? Ini bermaksud fungsi didefinisikan sebagai berikut:

 def print_msg(msg): # This is the outer enclosing function def printer(): # This is the nested function print(msg) return printer # returns the nested function # Now let's try calling this function. # Output: Hello another = print_msg("Hello") another()

Pengeluaran

 Helo

Itu tidak biasa.

Yang print_msg()fungsi dipanggil dengan tali "Hello"dan fungsi kembali terikat kepada nama lain. Semasa menelefon another(), mesej itu masih diingat walaupun kami sudah selesai menjalankan print_msg()fungsi tersebut.

Teknik ini di mana beberapa data ( "Hellodalam hal ini) melekat pada kod disebut penutupan di Python .

Nilai ini dalam ruang lingkup dikenang walaupun pemboleh ubah keluar dari ruang lingkup atau fungsi itu sendiri dikeluarkan dari ruang nama semasa.

Cuba jalankan yang berikut di shell Python untuk melihat hasilnya.

 >>> del print_msg >>> another() Hello >>> print_msg("Hello") Traceback (most recent call last):… NameError: name 'print_msg' is not defined

Di sini, fungsi yang dikembalikan masih berfungsi walaupun fungsi asal telah dipadamkan.

Bilakah kita mempunyai penutupan?

Seperti yang dilihat dari contoh di atas, kita mempunyai penutupan di Python apabila fungsi bersarang merujuk nilai dalam ruang lingkupnya.

Kriteria yang mesti dipenuhi untuk membuat penutupan di Python diringkaskan dalam perkara berikut.

  • Kita mesti mempunyai fungsi bersarang (fungsi di dalam fungsi).
  • Fungsi bersarang mesti merujuk kepada nilai yang ditentukan dalam fungsi lampiran.
  • Fungsi lampiran mesti mengembalikan fungsi bersarang.

Bilakah menggunakan penutup?

Jadi penutupan apa yang baik?

Penutupan dapat mengelakkan penggunaan nilai global dan menyediakan beberapa bentuk penyembunyian data. Ia juga dapat memberikan penyelesaian berorientasikan objek untuk masalah tersebut.

Apabila terdapat beberapa kaedah (satu kaedah dalam kebanyakan kes) untuk dilaksanakan di dalam kelas, penutupan dapat memberikan penyelesaian alternatif dan lebih elegan. Tetapi apabila bilangan atribut dan kaedah bertambah besar, lebih baik melaksanakan kelas.

Berikut adalah contoh mudah di mana penutupan mungkin lebih disukai daripada menentukan kelas dan membuat objek. Tetapi keutamaan adalah semua anda.

 def make_multiplier_of(n): def multiplier(x): return x * n return multiplier # Multiplier of 3 times3 = make_multiplier_of(3) # Multiplier of 5 times5 = make_multiplier_of(5) # Output: 27 print(times3(9)) # Output: 15 print(times5(3)) # Output: 30 print(times5(times3(2)))

Pengeluaran

 27 15 30

Python Decorators juga menggunakan penutupan secara meluas.

Sebagai catatan, adalah baik untuk menunjukkan bahawa nilai-nilai yang tertutup dalam fungsi penutupan dapat diketahui.

Semua objek fungsi mempunyai __closure__atribut yang mengembalikan tupel objek sel jika itu adalah fungsi penutupan. Merujuk kepada contoh di atas, kita tahu times3dan times5merupakan fungsi penutupan.

 >>> make_multiplier_of.__closure__ >>> times3.__closure__ (,)

Objek sel mempunyai atribut cell_contents yang menyimpan nilai tertutup.

 >>> times3.__closure__(0).cell_contents 3 >>> times5.__closure__(0).cell_contents 5

Artikel menarik...