Penutupan (Closure) Python Dijelaskan: Cara Fungsi Bertingkat Mengambil Variabel
Python Closures
Temukan cara kerja penutupan Python, cara menentukannya, dan mengapa mereka penting untuk kode yang bersih dan efisien.
Nonlocal Variables in a Nested Function
Sebelum menjelajahi closures, penting untuk memahami nested functions dan nonlocal variables. Sebuah fungsi yang didefinisikan di dalam fungsi lain disebut nested function. Fungsi semacam itu dapat membaca variabel dari cakupan enclosing mereka.
Di Python, variabel non-local ini bersifat read-only secara default. Untuk memodifikasi mereka, Anda harus secara eksplisit mendeklarasikan variabel sebagai nonlocal di dalam nested function.
Berikut adalah contoh sederhana yang menunjukkan nested function mengakses variabel non-local.
def print_msg(msg):
# Outer function
def printer():
# Nested function
print(msg)
printer()
print_msg("Hello")
Output
Hello
Nested function printer() dapat mengakses variabel msg dari cakupan luarnya.
Defining a Closure Function
Bagaimana jika outer function mengembalikan nested function alih-alih memanggilnya? Kode akan terlihat seperti ini:
def print_msg(msg):
def printer():
print(msg)
return printer # Return the nested function
# Store the returned function
another = print_msg("Hello")
another()
Output
Hello
Perhatikan bahwa fungsi printer masih ingat nilai msg bahkan setelah print_msg selesai dieksekusi. Fenomena ini—di mana suatu fungsi mempertahankan akses ke variabel dari cakupan tempat ia didefinisikan—disebut closure di Python.
Untuk menggambarkan lebih jauh, hapus fungsi asli dan lihat bahwa fungsi yang dikembalikan masih berfungsi:
>>> del print_msg
>>> another()
Hello
>>> print_msg("Hello")
Traceback (most recent call last):
... NameError: name 'print_msg' is not defined
Fungsi yang dikembalikan terus berfungsi karena ia menangkap data yang diperlukan dalam closurenya.
When Do We Have Closures?
Di Python, closure ada ketika nested function:
- didefinisikan di dalam fungsi lain.
- mereferensikan variabel dari enclosing function-nya.
- dikembalikan oleh outer function.
When to Use Closures?
Closures menawarkan beberapa keuntungan:
- Mereka menghilangkan kebutuhan akan variabel global, meningkatkan enkapsulasi.
- Mereka menyediakan alternatif ringan untuk kelas satu metode, menjaga kode tetap ringkas.
- Mereka memungkinkan pola fungsional seperti decorators, di mana wrapper function membutuhkan akses ke argumen fungsi asli.
Berikut adalah contoh umum: sebuah factory yang membuat fungsi pengali.
def make_multiplier_of(n):
def multiplier(x):
return x * n
return multiplier
# Create specific multipliers
times3 = make_multiplier_of(3)
times5 = make_multiplier_of(5)
print(times3(9)) # 27
print(times5(3)) # 15
print(times5(times3(2))) # 30
Output
27 15 30
Sintaks decorator Python sangat bergantung pada closures. Saat Anda menulis decorator, wrapper function menangkap fungsi yang di-decorate, membentuk closure.
Untuk memeriksa closure, gunakan atribut __closure__. Ia mengembalikan tuple cell objects yang menyimpan nilai tertutup. Misalnya:
>>> make_multiplier_of.__closure__
>>> times3.__closure__
(<cell at 0x0000000002D155B8: int object at 0x000000001E39B6E0>,)
Setiap cell atribut cell_contents menyimpan nilai aktual yang tertangkap oleh closure:
>>> times3.__closure__[0].cell_contents
3
>>> times5.__closure__[0].cell_contents
5
Memahami closures memberdayakan Anda untuk menulis kode Python yang lebih bersih, lebih modular yang menghindari globals yang tidak perlu dan mengadopsi paradigma fungsional.