2.23. Dekorator¶
Dekorator adalah potongan sintaks yang membungkus fungsi (atau metode) dalam fungsi lain. Pembungkus dapat menambahkan perilaku sebelum dan sesudah panggilan asli, mengganti nilai kembalian, atau melampirkan metadata. Bentuknya adalah:
@wrapper
def f():
...
Baris @wrapper setara dengan f = wrapper(f) -- fungsi f dibangun secara normal, kemudian diserahkan ke wrapper, dan hasilnya terikat kembali ke nama f.
Dekorator mengambil fungsi masuk dan mengembalikan fungsi baru.¶
2.23.1. Dekorator metode bawaan¶
Beberapa dekorator disertakan dengan Python dan digunakan di dalam badan kelas.
2.23.1.1. @property¶
Mengubah metode menjadi atribut terkomputasi. Pemanggil mengaksesnya seolah-olah itu adalah atribut biasa (tanpa tanda kurung), tetapi sebuah metode berjalan pada setiap pembacaan:
class Circle:
def __init__(self, radius):
self.radius = radius
@property
def area(self):
return 3.14159 * self.radius * self.radius
c = Circle(5)
print(c.area) # 78.53975 -- no parentheses
Gunakan ketika atribut yang terlihat sederhana memerlukan komputasi kecil di baliknya. Jika pekerjaan itu mahal, lebih baik gunakan metode biasa -- pemanggil tidak mengharapkan pembacaan atribut menjadi lambat.
2.23.1.2. @classmethod¶
Mendefinisikan metode yang menerima kelas sebagai argumen pertamanya alih-alih instans. Parameter pertama secara konvensional diberi nama cls:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
@classmethod
def origin(cls):
return cls(0, 0)
p = Point.origin()
Metode kelas adalah cara standar untuk menyediakan konstruktor alternatif -- fungsi pabrik yang mengembalikan instans yang dibangun dengan cara non-default.
2.23.1.3. @staticmethod¶
Mendefinisikan metode yang tidak menerima instans maupun kelas -- itu hanyalah fungsi biasa yang berada di namespace kelas karena alasan organisasi:
class Temperature:
@staticmethod
def c_to_f(c):
return c * 9 / 5 + 32
Temperature.c_to_f(100) # 212.0
Gunakan dengan hemat; jika fungsi benar-benar tidak ada hubungannya dengan status kelas, fungsi biasa di tingkat modul biasanya lebih bersih.
2.23.2. Menulis dekorator kustom¶
Dekorator adalah fungsi yang mengambil fungsi dan mengembalikan fungsi. Bentuk minimumnya:
def log_calls(func):
def wrapper(*args, **kwargs):
print("calling", func.__name__)
return func(*args, **kwargs)
return wrapper
@log_calls
def add(a, b):
return a + b
add(2, 3)
Output:
calling add
wrapper menutup func dan meneruskan semuanya ke sana. *args / **kwargs memungkinkannya bekerja pada fungsi apa pun, bukan hanya yang dua argumen. Pola ini adalah fondasi dekorator yang lebih rumit (pengaturan waktu, cache, coba-lagi-saat-gagal) tetapi intinya selalu sama: ambil fungsi masuk, kembalikan fungsi keluar.