Cara Membuat dan Menggunakan Dekorator dengan Python

Pelajari cara menulis dan menerapkan dekorator dengan Python. Menguasai fungsi pembungkusan, mengubah perilaku, menangani argumen, dan melestarikan metadata dengan pembungkus.

Coba Solusi ini di Editor

Ikhtisar

Dekorator adalah salah satu fitur sintaksis Python yang paling elegan dan kuat, memungkinkan Anda mengubah perilaku suatu fungsi atau kelas tanpa mengubah kodenya secara permanen. Mereka banyak digunakan untuk masalah lintas sektoral seperti mencatat waktu eksekusi, menerapkan autentikasi pengguna, menyimpan hasil dalam cache (memoisasi), dan mengaudit titik akhir API.

Di balik terpalnya, dekorator adalah fungsi tingkat tinggi yang menggunakan fungsi lain sebagai argumen, mendefinisikan fungsi pembungkus bersarang yang memasukkan beberapa logika khusus, dan mengembalikan fungsi pembungkus ini. Python menyediakan sintaksis steno yang bersih menggunakan simbol `@` untuk menerapkan dekorator ke fungsi, menjadikannya elegan secara visual.

Saat menulis dekorator, Anda biasanya ingin fungsi yang dihias mendukung sejumlah argumen posisi dan kata kunci. Anda dapat mencapainya dengan merancang fungsi wrapper bertingkat untuk menerima `*args` dan `**kwargs` dan meneruskannya ke fungsi target. Selain itu, Anda harus menggunakan `functools.wraps` pada fungsi wrapper untuk mempertahankan docstring dan metadata nama fungsi asli.

Kode & Output Eksekusi

Skrip ini mendemonstrasikan penulisan dekorator logging dan menggabungkan fungsi untuk memeriksa input, output, dan metadata.

decorators_tutorial.py
Coba di Editor
from functools import wraps

# 1. Defining a decorator
def log_execution(func):
    @wraps(func) # Preserves original function metadata
    def wrapper(*args, **kwargs):
        print(f"[Log] Calling function: {func.__name__} with args: {args}")
        result = func(*args, **kwargs)
        print(f"[Log] Finished {func.__name__}. Result: {result}")
        return result
    return wrapper

# 2. Applying the decorator using @ syntax
@log_execution
def add_numbers(a, b):
    """Adds two numbers and returns the sum."""
    return a + b

# 3. Invoking the decorated function
sum_result = add_numbers(15, 25)
print("Sum Result:", sum_result)

# Verifying metadata preservation
print("Docstring preserved:", add_numbers.__doc__)
Keluaran Terminal
[Log] Calling function: add_numbers with args: (15, 25)
[Log] Finished add_numbers. Result: 40
Sum Result: 40
Docstring preserved: Adds two numbers and returns the sum.

Implementasi Langkah demi Langkah

  • Tentukan fungsi dekorator luar yang menggunakan fungsi target sebagai argumen.
  • Impor dan terapkan @functools.wraps(func) pada fungsi wrapper bertingkat Anda untuk melindungi metadata asli.
  • Implementasikan wrapper(*args, **kwargs) untuk menangkap variabel input, memasukkan logika, dan memanggil fungsi target.
  • Mengembalikan objek fungsi wrapper dari blok header dekorator.
  • Terapkan dekorator menggunakan @decorator_name tepat di atas tanda tangan fungsi target.

Pertanyaan yang Sering Diajukan

Mengapa @functools.wraps diperlukan di dalam dekorator?

Tanpa wraps, fungsi yang dihias akan kehilangan identitas aslinya (atribut __name__ dan __doc__-nya digantikan oleh fungsi wrapper yang disarangkan), sehingga proses debug dan introspeksi kode menjadi sulit.

Bisakah saya menerapkan beberapa dekorator ke satu fungsi?

Iya! Anda dapat merangkai dekorator dengan menumpuk beberapa baris @. Python menerapkannya dari bawah ke atas (yang paling dekat dengan definisi fungsi dijalankan terlebih dahulu).

Topik Terkait

Sumber Daya Python yang Direkomendasikan

Perluas pengetahuan Anda dengan tutorial interaktif terkait, lembar contekan, dan perbandingan kode.