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.