Dekorator di Python

Dekorator di Python

Artikel ini menjelaskan dekorator di Python.

YouTube Video

Dekorator di Python

Dekorator Python adalah fitur yang kuat yang digunakan untuk menambahkan fungsionalitas tambahan ke fungsi atau metode. Dekorator memungkinkan Anda menambahkan fungsionalitas baru tanpa mengubah kode yang ada, sehingga meningkatkan kegunaan kembali dan pemeliharaan kode.

Dasar-dasar Dekorator

Dekorator Python bekerja dengan mengambil fungsi sebagai argumen dan mengembalikan fungsi baru dengan fungsionalitas tambahan. Dengan menggunakan dekorator, Anda dapat dengan mudah menambahkan pra-pemrosesan atau pasca-pemrosesan pada fungsi.

Tanpa dekorator, mengubah perilaku fungsi memerlukan pengeditan langsung pada fungsi itu sendiri. Dengan dekorator, Anda dapat memperluas fungsionalitas tanpa mengubah implementasi aslinya.

Struktur Dasar Sebuah Dekorator

 1def my_decorator(func):
 2    def wrapper():
 3        print("Before the function call")
 4        func()
 5        print("After the function call")
 6    return wrapper
 7
 8@my_decorator
 9def say_hello():
10    print("Hello!")
11
12say_hello()

Dalam contoh ini, fungsi my_decorator berfungsi sebagai dekorator, membungkus fungsi say_hello. Dekorator diaplikasikan menggunakan sintaks @my_decorator, dan ketika say_hello() dipanggil, pra- dan pasca-pemrosesan yang disediakan oleh dekorator dieksekusi secara otomatis.

Cara Kerja Dekorator

Dekorator bekerja dalam langkah-langkah berikut.

  1. Dekorator mengambil fungsi (atau metode) sebagai argumen.

  2. Dekorator mendefinisikan fungsi pembungkus untuk menjalankan fungsi asli.

  3. Fungsi pembungkus melakukan pemrosesan tambahan sebelum atau sesudah menjalankan fungsi asli.

  4. Dekorator mengembalikan fungsi pembungkus. Sebagai hasilnya, fungsi asli digantikan dengan fungsi baru yang telah didekorasi.

Dekorator untuk Fungsi dengan Argumen

Ketika menerapkan dekorator pada fungsi dengan argumen, fungsi pembungkus harus disesuaikan untuk menerima argumen tersebut.

 1def my_decorator(func):
 2    def wrapper(*args, **kwargs):
 3        print("Before the function call")
 4        result = func(*args, **kwargs)
 5        print("After the function call")
 6        return result
 7    return wrapper
 8
 9@my_decorator
10def greet(name):
11    print(f"Hello, {name}!")
12
13greet("Alice")

Dengan menggunakan *args dan **kwargs, dimungkinkan untuk menangani fungsi yang menerima jumlah argumen dan argumen kata kunci berapa pun. Ini memungkinkan dekorator diterapkan secara umum pada fungsi dengan jenis argumen apa pun.

Contoh Penerapan Dekorator

Dekorator untuk Logging

Dekorator sering digunakan untuk menambahkan fungsi pencatatan (logging). Sebagai contoh, dengan membuat dekorator yang mencatat sebelum dan setelah eksekusi sebuah fungsi, Anda dapat merekam kapan fungsi tersebut dipanggil dan berapa lama waktu yang dibutuhkan untuk eksekusinya.

 1import time
 2
 3def log_time(func):
 4    def wrapper(*args, **kwargs):
 5        start_time = time.time()
 6        print(f"Calling function '{func.__name__}'...")
 7        result = func(*args, **kwargs)
 8        end_time = time.time()
 9        print(f"Function '{func.__name__}' completed in {end_time - start_time} seconds")
10        return result
11    return wrapper
12
13@log_time
14def long_task(duration):
15    time.sleep(duration)
16    print("Task completed!")
17
18long_task(2)

Dalam contoh ini, dekorator log_time mengukur waktu eksekusi sebuah fungsi dan mencatatnya sebagai log. Fungsi long_task dibungkus dengan dekorator, dan waktu eksekusinya dicatat selama runtime.

Dekorator untuk Manajemen Izin

Dekorator juga dapat digunakan untuk manajemen izin. Sebagai contoh, Anda dapat membatasi pemrosesan dengan memeriksa apakah pengguna memiliki izin tertentu.

 1def requires_permission(user_role):
 2    def decorator(func):
 3        def wrapper(*args, **kwargs):
 4            if user_role != "admin":
 5                print("Permission denied!")
 6                return
 7            return func(*args, **kwargs)
 8        return wrapper
 9    return decorator
10
11@requires_permission("admin")
12def delete_user(user_id):
13    print(f"User {user_id} has been deleted.")
14
15delete_user(123)  # Executed
16delete_user = requires_permission("guest")(delete_user)
17delete_user(456)  # Permission denied!

Dekorator requires_permission membatasi eksekusi sebuah fungsi berdasarkan peran pengguna. Dengan mengkonsolidasikan logika semacam itu ke dalam sebuah dekorator, Anda dapat mencegah logika manajemen izin tersebar di seluruh kode Anda, sehingga meningkatkan keterbacaan.

Dekorator Bertumpuk

Dimungkinkan untuk menerapkan beberapa dekorator. Ketika beberapa dekorator diterapkan ke satu fungsi, mereka akan dieksekusi secara berurutan dari atas ke bawah.

 1def uppercase(func):
 2    def wrapper(*args, **kwargs):
 3        result = func(*args, **kwargs)
 4        return result.upper()
 5    return wrapper
 6
 7def exclaim(func):
 8    def wrapper(*args, **kwargs):
 9        result = func(*args, **kwargs)
10        return result + "!"
11    return wrapper
12
13@uppercase
14@exclaim
15def greet(name):
16    return f"Hello, {name}"
17
18print(greet("Alice"))  # "HELLO, ALICE!"

Pada contoh ini, dua dekorator diterapkan pada fungsi greet. Dekorator @exclaim menambahkan tanda seru di akhir string, dan kemudian @uppercase mengubah string menjadi huruf kapital.

Dekorator untuk Metode Kelas

Dekorator juga dapat digunakan pada metode kelas. Ini sangat berguna ketika Anda ingin mengontrol perilaku metode di dalam sebuah kelas. Saat menerapkan dekorator pada metode kelas, Anda perlu memperhatikan argumen seperti self atau cls.

 1def log_method_call(func):
 2    def wrapper(self, *args, **kwargs):
 3        print(f"Calling method '{func.__name__}'...")
 4        return func(self, *args, **kwargs)
 5    return wrapper
 6
 7class MyClass:
 8    @log_method_call
 9    def greet(self, name):
10        print(f"Hello, {name}")
11
12obj = MyClass()
13obj.greet("Bob")

Dalam contoh ini, dekorator log_method_call diterapkan pada metode greet untuk mencatat log saat metode tersebut dipanggil.

Perhatian dalam Penggunaan Dekorator

Ada beberapa hal yang perlu dipertimbangkan saat menggunakan dekorator. Dekorator dapat berpotensi mengubah nama fungsi asli dan string dokumentasi (misalnya, __name__ atau __doc__), sehingga direkomendasikan untuk menggunakan functools.wraps untuk menjaga informasi ini.

1import functools
2
3def my_decorator(func):
4    @functools.wraps(func)
5    def wrapper(*args, **kwargs):
6        print("Before the function call")
7        return func(*args, **kwargs)
8    return wrapper

Penggunaan @functools.wraps memastikan bahwa metadata fungsi asli diteruskan dengan benar ke fungsi pembungkus.

Ringkasan

Dekorator Python adalah alat yang sangat kuat yang memungkinkan Anda dengan ringkas menambahkan fungsionalitas tambahan ke fungsi dan metode. Dekorator dapat digunakan dalam berbagai skenario untuk mengurangi duplikasi kode dan meningkatkan pemeliharaan serta kegunaan kembali. Dengan memahami cara kerja dekorator, Anda dapat menulis kode yang lebih efisien dan fleksibel.

Anda dapat mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Silakan periksa juga saluran YouTube kami.

YouTube Video