0Pricing
Python Academy · Pelajaran

Menulis Decorator Kustom

Buat decorator menggunakan fungsi pembungkus dan functools.wraps.

Menulis Decorator Kustom adalah pelajaran Python Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Python Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Python Academy mencakup 4 pelajaran total.

Pendahuluan

Dekorator adalah fungsi yang membungkus fungsi lain untuk menambahkan perilaku sebelum atau sesudahnya tanpa mengubah fungsi asli.

Apa Itu Dekorator?

@decorator di atas sebuah fungsi merupakan sintaks ringkas untuk: func = decorator(func). Dekorator menerima fungsi tersebut dan mengembalikan wrapper.
def shout(func):
    def wrapper(*a, **kw):
        result = func(*a, **kw)
        return str(result).upper()
    return wrapper
@shout
def greet(name): return f'hello {name}'
print(greet('Alice'))

Pola Wrapper

Fungsi wrapper memiliki signature yang sama dengan fungsi asli. Wrapper memanggil fungsi asli di dalamnya dan menambahkan perilaku di sekelilingnya.
def timer(func):
    import time
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f'{func.__name__} took {time.time()-start:.4f}s')
        return result
    return wrapper
@timer
def slow(): import time; time.sleep(0.01)
slow()

functools.wraps

@wraps(func) pada wrapper mempertahankan __name__, __doc__, dan __annotations__ dari fungsi asli.
from functools import wraps
def log(func):
    @wraps(func)
    def wrapper(*a, **kw):
        print(f'calling {func.__name__}')
        return func(*a, **kw)
    return wrapper
@log
def add(a, b): return a + b
print(add.__name__)
add(1, 2)

Dekorator dengan Argumen

Dekorator dengan argumen memerlukan satu tingkat pembungkusan tambahan: fungsi pabrik yang menerima argumen tersebut dan mengembalikan dekorator.
def repeat(n):
    def decorator(func):
        from functools import wraps
        @wraps(func)
        def wrapper(*a, **kw):
            for _ in range(n): func(*a, **kw)
        return wrapper
    return decorator
@repeat(3)
def hi(): print('hi')
hi()

Menumpuk Dekorator

Beberapa dekorator ditumpuk dari bawah ke atas: @d2 @d1 berarti func = d2(d1(func)). Dekorator terluar (yang paling atas) dijalankan terakhir.
def bold(f):
    from functools import wraps
    @wraps(f)
    def w(*a,**k): return '<b>' + f(*a,**k) + '</b>'
    return w
def italic(f):
    from functools import wraps
    @wraps(f)
    def w(*a,**k): return '<i>' + f(*a,**k) + '</i>'
    return w
@bold
@italic
def text(): return 'hello'
print(text())

Dekorator Berbasis Kelas

Kelas yang memiliki __call__ dapat menjadi dekorator. Kelas tersebut menyimpan keadaan di antara pemanggilan.
class Counter:
    def __init__(self, func): self.func,self.count=func,0
    def __call__(self, *a, **kw):
        self.count+=1
        return self.func(*a, **kw)
@Counter
def greet(name): return f'hi {name}'
greet('Alice'); greet('Bob')
print(greet.count)

Dekorator Memoisasi

Simpan hasil sebelumnya dalam tembolok agar tidak perlu menghitung ulang: if args in cache: return cache[args]. functools.lru_cache menyediakan kemampuan ini secara bawaan.
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
    if n < 2: return n
    return fib(n-1) + fib(n-2)
print(fib(30))

Dekorator Otorisasi

Dekorator umum digunakan untuk mengendalikan akses: periksa apakah pengguna sudah masuk sebelum menjalankan fungsi.
def requires_auth(func):
    from functools import wraps
    @wraps(func)
    def wrapper(user, *a, **kw):
        if not user.get('authenticated'):
            raise PermissionError('Not authenticated')
        return func(user, *a, **kw)
    return wrapper
@requires_auth
def dashboard(user): return 'Welcome!'
try: dashboard({'authenticated': False})
except PermissionError as e: print(e)

Dekorator Percobaan Ulang

Bungkus sebuah fungsi agar dicoba ulang saat gagal: for _ in range(retries): try: return func() except Exception: pass
import random
from functools import wraps
def retry(times=3):
    def dec(func):
        @wraps(func)
        def wrapper(*a, **kw):
            for i in range(times):
                try: return func(*a, **kw)
                except Exception as e:
                    if i==times-1: raise
        return wrapper
    return dec
@retry(3)
def flaky():
    if random.random()<0.7: raise ValueError
    return 'ok'
try: print(flaky())
except ValueError: print('failed')

Praktik Terbaik Dekorator

Selalu gunakan @functools.wraps. Pastikan setiap dekorator memiliki satu tujuan. Dokumentasikan hal yang ditambahkannya. Uji dekorator secara terpisah dari fungsi yang dihiasnya.
from functools import wraps
def validate_positive(func):
    @wraps(func)
    def wrapper(x, *a, **kw):
        if x <= 0: raise ValueError(f'{x} must be positive')
        return func(x, *a, **kw)
    return wrapper
@validate_positive
def sqrt(x): return x**0.5
print(sqrt(9))

Pemeriksaan Singkat

Apa yang dilakukan @functools.wraps(func) saat diterapkan pada wrapper?

Ringkasan

Dekorator: func = decorator(func). Gunakan wrapper(*args, **kwargs). @wraps mempertahankan metadata. Dekorator berparameter menambahkan satu tingkat pembungkusan. Tumpuk dengan beberapa @decorators.

Lanjutkan

Kemajuan Anda sangat baik! Lanjutkan untuk menguasai konsep berikutnya.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Menulis Decorator Kustom” gratis?

Ya — teks lengkap “Menulis Decorator Kustom” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Python Academy, upgrade ke CoddyKit PRO. Kursus Python Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Menulis Decorator Kustom”?

Buat decorator menggunakan fungsi pembungkus dan functools.wraps. Kamu berlatih Python Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Python Academy?

Tidak diperlukan pengalaman sebelumnya. Python Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.

Berapa lama pelajaran “Menulis Decorator Kustom” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Python Academy ini?

Ya. Setiap pelajaran Python Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Fungsi sebagai Objek Kelas Satu
  2. Menulis Decorator Kustom
  3. Decorator @property
  4. @classmethod dan @staticmethod
← Kembali ke Python Academy