Dekorator Python: Apa Itu dan Bagaimana Cara Menggunakannya?
Table of content:
Saat menulis kode, terkadang Anda perlu memperluas fungsi tanpa benar-benar mengubah kodenya secara langsung. Dalam situasi ini, dekorator dapat membantu.
Dekorator adalah jenis fungsi khusus yang membungkus fungsi lain. Mereka membiarkan Anda menambahkan kode ekstra sebelum dan sesudah fungsi asli, memberikan cara yang elegan untuk memperluas fungsi yang ada.
Bagaimana Dekorator Bekerja?
Fungsi Python adalah warga negara kelas satu, yang berarti Anda dapat menetapkannya ke variabel, meneruskannya sebagai argumen ke fungsi lain, dan mengembalikannya dari fungsi. Properti ini memfasilitasi pembuatan dekorator.
Fungsi dekorator mengembalikan fungsi lain. Ini bertindak sebagai meta-fungsi yang menambahkan fungsionalitas ekstra ke fungsi target. Saat Anda mendekorasi suatu fungsi, Python memanggil fungsi dekorator dan meneruskan fungsi target sebagai argumen.
Fungsi dekorator dapat melakukan tindakan yang diperlukan sebelum dan sesudah memanggil fungsi target. Itu juga dapat memodifikasi perilaku fungsi target dengan mengembalikan fungsi baru atau mengganti fungsi asli sama sekali.
Membuat Fungsi Dekorator
Untuk membuat dekorator, tentukan fungsi yang mengambil fungsi target sebagai argumen dan mengembalikan fungsi pembungkus. Fungsi pembungkus berisi fungsionalitas tambahan dan panggilan ke fungsi target.
def decorator_func(target_func):
def wrapper_func():
target_func()
return wrapper_func
Di Sini, dekorator_fungsi mengambil target_fungsi sebagai argumen. Itu kembali wrapper_func yang memanggil target_fungsi Dan berisi fungsi tambahan.
Dekorasi Fungsi Dengan Dekorator
Untuk menerapkan dekorator ke fungsi target, gunakan @ sintaks dan tempatkan dekorator langsung di atas definisi fungsi target.
@decorator_func
def my_function():
pass
Di sini, dekorator_fungsi menghiasi my_function. Jadi, kapan pun Anda menggunakannya my_functionpanggilan Python dekorator_fungsi dan berlalu my_function sebagai argumen.
Perhatikan bahwa fungsi dekorator tidak menggunakan tanda kurung buka dan tutup.
Untuk kejelasan, the @ sintaks lebih seperti gula sintaksis. Anda dapat meneruskan fungsi target langsung ke fungsi dekorator sebagai argumen:
func = decorator_func(my_function)
Menangani Argumen Fungsi Dalam Dekorator
Untuk menangani argumen fungsi di dalam dekorator, gunakan * argumen Dan **kwargs dalam fungsi pembungkus. Ini memungkinkan dekorator untuk menerima sejumlah argumen posisi dan kata kunci.
def decorator_func(target_func):
def wrapper_func(*args, **kwargs):
result = target_func(*args, **kwargs)
return result
return wrapper_func
Itu * argumen Dan **kwargs di dalam wrapper_func pastikan dekorator dapat menangani argumen apa pun yang Anda berikan ke fungsi target.
Dekorator Dengan Argumen
Dekorator juga dapat mengambil argumen mereka sendiri. Ini memberi Anda cara yang lebih fleksibel untuk mendekorasi fungsi.
def my_decorator(num_times):
def wrapper(func):
def inner(*args, **kwargs):
for _ in range(num_times):
func(*args, **kwargs)
return inner
return wrapper@my_decorator(2)
def greet(name):
print(f"Hello, {name}.")
Itu my_decorator fungsi mengambil angka (2) sebagai argumen dan mengembalikan a pembungkus fungsi. Fungsi itu mengembalikan an batin fungsi yang memanggil fungsi yang dihias (menyapa, dalam hal ini) beberapa kali (2). Sehingga:
greet("Prince")
Akan mencetak “Halo, Pangeran” dua kali.
Penggunaan Praktis Dekorator
Anda dapat menggunakan dekorator untuk berbagai tujuan, seperti logging, caching, validasi input, dan pengoptimalan kinerja.
Dekorator Penebangan
Anda dapat menggunakan dekorator logging untuk mencatat informasi tentang eksekusi suatu fungsi. Ini dapat membantu men-debug atau memantau perilaku fungsi tertentu.
import loggingdef my_logger(func):
def wrapper(*args, **kwargs):
logging.info("Entering function: %s", func.__name__)
result = func(*args, **kwargs)
logging.info("Exiting function: %s", func.__name__)
return result
return wrapper
Penghias Waktu
Anda dapat menggunakan dekorator waktu untuk mengukur waktu eksekusi eksekusi fungsi. Ini berguna untuk membuat profil atau mengoptimalkan kode.
import timedef timing_decorator(target_func):
def wrapper_func(*args, **kwargs):
start_time = time.time()
result = target_func(*args, **kwargs)
end_time = time.time()
total = end_time - start_time
print(f"Function {target_func.__name__} took {total} seconds to run")
return result
return wrapper_func
Terapkan dekorator:
@my_logger
@timing_decorator
def bg_task(n):
print(f"Background Task, {n}.")
return "Result !!!"if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
print(bg_task("CPU is Dancing"))
Sekarang Anda akan melihat debug saat fungsi berjalan dan ringkasan waktu yang diperlukan.
Dekorator Otorisasi
Anda dapat menggunakan dekorator otorisasi untuk memeriksa apakah pengguna memiliki izin yang diperlukan untuk mengakses fungsi tertentu. Sebagian besar kerangka kerja web menggunakan fitur ini untuk menambahkan lapisan keamanan. Contoh umum adalah milik Django @login dibutuhkan penghias.
def authorization_decorator(target_func):
def wrapper_func(*args, **kwargs):
if is_user_authorized():
result = target_func(*args, **kwargs)
return result
else:
raise PermissionError("Unauthorized access") return wrapper_func
Contoh-contoh ini menggambarkan beberapa kasus penggunaan umum untuk dekorator. Anda dapat membuat dekorator untuk berbagai keperluan, tergantung pada kebutuhan spesifik Anda.
Konsep Dekorator Tingkat Lanjut
Dekorator mudah diimplementasikan dan digunakan. Tetapi mereka juga kuat dan dapat memberikan lebih banyak fleksibilitas dan kontrol.
Dekorator Berbasis Kelas
Selain dekorator berbasis fungsi, Python juga mendukung dekorator berbasis kelas.
Dekorator berbasis kelas adalah kelas yang mendefinisikan a __panggilan__ metode ajaib, memungkinkan Anda untuk menggunakan kelas sebagai dekorator.
class DecoratorClass:
def __init__(self, target_func):
self.target_func = target_func def __call__(self, *args, **kwargs):
print("Calling function")
result = self.target_func(*args, **kwargs)
print("Function called")
return result
Contoh ini mendefinisikan kelas dekorator. Saat Anda mendekorasi suatu fungsi dengan DekoratorClassPython memanggil __panggilan__ metode ajaib, yang menerapkan fungsionalitas dekorator ke fungsi target.
Dekorator berbasis kelas dapat mempertahankan keadaan di beberapa panggilan dengan menyimpan informasi dalam variabel instan. Ini memungkinkan Anda implementasi dekorator yang lebih maju dan fleksibel.
Dekorator Nesting dan Chaining
Misalkan Anda perlu menggabungkan berbagai jenis fungsionalitas menjadi satu unit untuk tindakan terkait pada suatu fungsi. Anda dapat mencapainya dengan menerapkan beberapa dekorator ke satu fungsi.
def decorator1(func):
def wrapper(*args, **kwargs):
print("Decorator1...")
return func(*args, **kwargs) return wrapper
def decorator2(func):
def wrapper(*args, **kwargs):
print("Decorator2...")
return func(*args, **kwargs)
return wrapper
@decorator1
@decorator2
def my_function(n):
print(n)
Di sini, keduanya dekorator1 Dan dekorator2 menghias my_function. Setiap kali Anda menggunakan my_functionfungsi dari dekorator1 berlaku pertama, maka dari itu dekorator2.
Contoh umum adalah ketika Anda perlu menerapkan a pasca-saja permintaan dan login dibutuhkan fungsionalitas ke tampilan Django.
Manfaat Dekorator
Dekorator menawarkan beberapa keuntungan yang menjadikannya penting dalam banyak proyek Python:
- Penggunaan Ulang Kode: Mempromosikan penggunaan kembali kode dengan memisahkan masalah lintas sektoral dari logika inti.
- Prinsip KERING: Mematuhi prinsip Jangan Ulangi Sendiri dengan menerapkan fungsionalitas yang sama ke beberapa fungsi tanpa duplikasi kode.
- Keterbacaan dan Pemeliharaan: Meningkatkan keterbacaan dan pemeliharaan kode dengan menjaga fungsionalitas utama tetap fokus dan jelas.
- Gaya Pythonic: Sejajar dengan gaya Pythonic dengan menekankan kode yang bersih, ekspresif, dan mudah dibaca.
Untuk alasan ini, Anda harus memanfaatkan dekorator jika memungkinkan.
Praktik Terbaik untuk Menggunakan Dekorator
Saat bekerja dengan dekorator, Anda harus mengikuti praktik terbaik tertentu:
- Pertahankan fungsi dekorator agar terfokus pada masalah tertentu, seperti logging atau caching. Ini mempromosikan kode modular dan membuat dekorator lebih fleksibel.
- Membuat dekorator dapat dikonfigurasi dengan menggunakan parameter dan menghindari nilai hard-coded. Ini memungkinkan Anda menyesuaikan perilaku dekorator saat menerapkannya ke berbagai fungsi.
- Berikan deskripsi yang jelas dan ringkas tentang tujuan dekorator, parameternya (jika ada), dan perilaku yang diharapkan saat diterapkan ke suatu fungsi.
- Jika dekorator memiliki efek samping, seperti memodifikasi perilaku fungsi atau memperkenalkan dependensi tambahan, dokumentasikan dengan jelas efek ini untuk referensi di masa mendatang.
- Tulis tes unit untuk dekorator Anda untuk memastikannya berperilaku seperti yang Anda harapkan. Uji berbagai skenario dan kasus tepi untuk mencakup berbagai situasi.
Bekerja Dengan Fungsi di Python
Dekorator adalah salah satu area inti di mana fungsi unggul. Secara umum fungsi Python adalah blok bangunan mendasar untuk mengatur dan menggunakan kembali kode. Mereka memungkinkan Anda untuk merangkum fungsionalitas, meneruskan data, dan mengembalikan hasil.
Memahami cara mendefinisikan dan menggunakan fungsi sangat penting untuk pemrograman Python yang efektif.