Penutupan Python: Bagaimana Cara Menggunakannya dan Mengapa?

Dalam tutorial ini, Anda akan belajar tentang penutupan Python, cara menentukan penutupan, dan alasan Anda harus menggunakannya.

Variabel nonlokal dalam fungsi bertingkat

Sebelum membahas tentang closure, kita harus terlebih dahulu memahami apa itu fungsi bersarang dan variabel nonlokal.

Fungsi yang didefinisikan di dalam fungsi lain disebut fungsi bersarang. Fungsi bersarang dapat mengakses variabel dari cakupan yang melingkupi.

Di Python, variabel non-lokal ini hanya-baca secara default dan kita harus mendeklarasikannya secara eksplisit sebagai non-lokal (menggunakan kata kunci nonlokal) untuk memodifikasinya.

Berikut adalah contoh fungsi bertingkat yang mengakses variabel non-lokal.

 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")

Keluaran

 Halo

Kita dapat melihat bahwa printer()fungsi bersarang dapat mengakses variabel msg non-lokal dari fungsi penutup.

Mendefinisikan Fungsi Penutupan

Dalam contoh di atas, apa yang akan terjadi jika baris terakhir dari fungsi print_msg()mengembalikan printer()fungsi alih-alih memanggilnya? Artinya, fungsi tersebut 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()

Keluaran

 Halo

Itu tidak biasa.

The print_msg()fungsi dipanggil dengan string "Hello"dan fungsi kembali terikat ke nama lain. Saat menelepon another(), pesan tersebut masih diingat meskipun kita sudah selesai menjalankan print_msg()fungsinya.

Teknik ini dimana beberapa data ( "Hellodalam hal ini) dilampirkan ke kode disebut closure dengan Python .

Nilai dalam lingkup pelingkup ini diingat bahkan ketika variabel keluar dari ruang lingkup atau fungsi itu sendiri dihapus dari namespace saat ini.

Coba jalankan perintah 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 meskipun fungsi aslinya telah dihapus.

Kapan kita ada penutupan?

Seperti yang terlihat dari contoh di atas, kita memiliki closure dengan Python ketika fungsi bersarang mereferensikan sebuah nilai dalam scope yang melingkupinya.

Kriteria yang harus dipenuhi untuk membuat penutupan dengan Python dirangkum dalam poin-poin berikut.

  • Kita harus memiliki fungsi bersarang (fungsi di dalam fungsi).
  • Fungsi bertingkat harus mengacu pada nilai yang ditentukan dalam fungsi penutup.
  • Fungsi penutup harus mengembalikan fungsi bersarang.

Kapan menggunakan closure?

Jadi, untuk apa closure itu bagus?

Penutupan dapat menghindari penggunaan nilai global dan menyediakan beberapa bentuk penyembunyian data. Ini juga dapat memberikan solusi berorientasi objek untuk masalah tersebut.

Ketika ada beberapa metode (satu metode dalam banyak kasus) yang akan diterapkan di kelas, closure dapat memberikan solusi alternatif dan lebih elegan. Tetapi ketika jumlah atribut dan metode semakin besar, lebih baik menerapkan kelas.

Berikut adalah contoh sederhana di mana closure mungkin lebih disukai daripada mendefinisikan kelas dan membuat objek. Tapi preferensi ada di tangan 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)))

Keluaran

 27 15 30

Python Decorators juga banyak menggunakan closure.

Pada catatan penutup, ada baiknya untuk menunjukkan bahwa nilai-nilai yang dimasukkan dalam fungsi closure dapat ditemukan.

Semua objek fungsi memiliki __closure__atribut yang mengembalikan tupel objek sel jika itu adalah fungsi penutupan. Mengacu pada contoh di atas, kita mengenal times3dan times5merupakan fungsi closure.

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

Objek sel memiliki atribut cell_contents yang menyimpan nilai tertutup.

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

Artikel yang menarik...