Traffine I/O

Bahasa Indonesia

2023-02-24

Decorator di Python

Apa itu Decorators

Decorator adalah fitur yang kuat di Python yang memungkinkan Anda untuk memodifikasi atau meningkatkan perilaku fungsi atau kelas tanpa mengubah kode sumbernya. Decorator adalah fungsi yang mengambil fungsi atau kelas lain sebagai input dan mengembalikan versi yang dimodifikasi.

Di Python, decorator direpresentasikan menggunakan simbol @ diikuti dengan nama fungsi decorator. Ketika fungsi atau kelas yang di-decorate dipanggil, sebenarnya ia memanggil versi yang dimodifikasi dari fungsi atau kelas aslinya.

Decorator dapat digunakan untuk melakukan berbagai tugas, seperti menambahkan fungsi logging atau timing, memaksa autentikasi atau otorisasi, caching hasil, dan banyak lagi. Mereka sangat berguna ketika Anda ingin memodifikasi perilaku fungsi atau kelas dengan cara yang dapat digunakan kembali di banyak fungsi atau kelas.

Cara Menggunakan Decorators

Berikut ini adalah langkah untuk menggunakan decorator di Python:

  1. Tentukan fungsi decorator
    Mulailah dengan mendefinisikan fungsi yang akan digunakan sebagai decorator. Fungsi ini harus mengambil fungsi atau kelas sebagai argumen dan mengembalikan versi yang dimodifikasi dari fungsi atau kelas tersebut.

  2. Tentukan fungsi atau kelas yang akan didekorasi
    Selanjutnya, tentukan fungsi atau kelas yang ingin Anda dekorasi. Fungsi atau kelas ini harus didefinisikan sebelum fungsi decorator.

  3. Terapkan decorator ke fungsi atau kelas
    Untuk menerapkan decorator ke fungsi atau kelas, gunakan simbol '@' diikuti dengan nama fungsi decorator. Letakkan sintaks ini pada baris segera sebelum definisi fungsi atau kelas yang akan didekorasi.

  4. Panggil fungsi atau kelas yang didekorasi
    Terakhir, panggil fungsi atau kelas yang didekorasi seperti yang biasanya dilakukan dengan memanggil fungsi atau kelas.

Berikut ini adalah contoh penggunaan decorator di Python:

python
def my_decorator(func):
    def wrapper():
        print("Before the function is called.")
        func()
        print("After the function is called.")
    return wrapper

@my_decorator
def say_hello():
    print("Hello, world!")

say_hello()

Dalam kode ini, kita mendefinisikan fungsi decorator my_decorator yang mengambil fungsi sebagai masukan dan mengembalikan versi yang dimodifikasi. Versi yang dimodifikasi menambahkan beberapa perilaku tambahan sebelum dan setelah fungsi asli dipanggil.

Kemudian kita menggunakan simbol @ untuk menerapkan decorator pada fungsi say_hello. Ini berarti bahwa ketika say_hello dipanggil, itu akan benar-benar memanggil versi yang dimodifikasi dari fungsi yang dibuat oleh decorator my_decorator.

Ketika kita menjalankan kode ini, keluarannya akan menjadi:

python
Before the function is called.
Hello, world!
After the function is called.

Ini menunjukkan bahwa decorator berhasil menambahkan beberapa perilaku tambahan sebelum dan setelah fungsi say_hello dipanggil.

Decorator Chaining

Decorator chaining adalah teknik yang powerful dalam Python yang memungkinkan Anda untuk menerapkan beberapa decorator ke sebuah fungsi atau kelas. Ini memungkinkan Anda untuk menambahkan berbagai lapisan fungsi ke kode Anda tanpa memodifikasi fungsi atau kelas asli.

Dalam Python, decorator diterapkan dalam urutan yang terdaftar. Ketika beberapa decorator diterapkan pada fungsi, hasilnya adalah rangkaian fungsi yang sudah didekorasi. Setiap decorator dalam rangkaian memodifikasi output dari decorator sebelumnya.

Decorator chaining dapat digunakan untuk melakukan berbagai tugas, seperti logging, timing, caching, authentication, dan lain-lain. Ini memungkinkan Anda untuk dengan mudah menggabungkan berbagai fungsionalitas dan membuat perilaku yang kompleks dengan hanya beberapa baris kode saja.

Berikut adalah contoh penggunaan decorator chaining dalam Python:

python
def decorator1(func):
    def wrapper():
        print("Decorator 1")
        func()
    return wrapper

def decorator2(func):
    def wrapper():
        print("Decorator 2")
        func()
    return wrapper

@decorator1
@decorator2
def my_function():
    print("Original function")

my_function()

Pada contoh di atas, kita telah mendefinisikan dua decorator, decorator1 dan decorator2. Kemudian kita menerapkan kedua decorator pada fungsi my_function menggunakan simbol @.

Ketika kita menjalankan kode ini, outputnya akan menjadi:

python
Decorator 1
Decorator 2
Original function

Ini menunjukkan bahwa decorator diterapkan dalam urutan yang terdaftar, dengan decorator1 diterapkan terlebih dahulu dan decorator2 diterapkan kedua. Output dari setiap decorator diteruskan ke decorator berikutnya dalam rangkaian, sehingga menghasilkan output akhir dari fungsi asli.

Decorator chaining adalah teknik yang powerful yang dapat membantu Anda menulis kode yang lebih bersih, modular, dan mudah dipahami. Dengan menggabungkan beberapa decorator, Anda dapat membuat perilaku yang kompleks yang mudah dipahami dan dipelihara.

Built-in Decorators di Python

Built-in decorator dalam Python adalah decorator bawaan yang telah ditentukan sebelumnya yang dapat digunakan untuk memodifikasi perilaku fungsi atau kelas. Decorator ini disediakan oleh bahasa Python itu sendiri dan dapat digunakan tanpa memerlukan kode tambahan.

Beberapa built-in decorator yang paling umum digunakan dalam Python termasuk @staticmethod, @classmethod, @property, dan @abstractmethod.

Decorator @staticmethod digunakan untuk mendefinisikan metode statis dalam kelas. Metode statis adalah metode yang dimiliki oleh kelas itu sendiri bukan oleh instance dari kelas tersebut.

Decorator @classmethod digunakan untuk mendefinisikan metode kelas dalam kelas. Metode kelas adalah metode yang terikat pada kelas dan bukan instance dari kelas tersebut.

Decorator @property digunakan untuk mendefinisikan properti dalam kelas. Properti memungkinkan Anda untuk mengakses dan memodifikasi atribut dari objek dengan cara yang tampak seperti akses atribut sederhana, tetapi sebenarnya menjalankan metode di latar belakang.

Decorator @abstractmethod digunakan untuk mendefinisikan metode abstrak dalam kelas. Metode abstrak adalah metode yang dideklarasikan tetapi tidak memiliki implementasi. Mereka dimaksudkan untuk dioverride oleh subclass dari kelas yang mengimplementasikan metode abstrak.

Dengan menggunakan built-in decorator dalam Python, Anda dapat dengan mudah memodifikasi perilaku fungsi atau kelas Anda tanpa harus menulis kode tambahan. Ini dapat membantu Anda menulis kode yang lebih modular dan mudah dipelihara.

Penggunaan Umum untuk Decorator

Decorator adalah alat yang kuat di Python yang memungkinkan Anda untuk memodifikasi perilaku fungsi atau kelas. Mereka dapat digunakan untuk berbagai tugas, seperti logging, timing, caching, authentication, dan lain-lain. Dalam artikel ini, saya akan membahas beberapa penggunaan umum untuk decorator di Python.

Logging

Salah satu penggunaan umum untuk decorator adalah untuk mencatat masukan dan keluaran fungsi. Ini dapat berguna untuk debugging dan memahami perilaku fungsi. Berikut adalah contoh logging decorator:

python
def log(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__} with args={args}, kwargs={kwargs}")
        result = func(*args, **kwargs)
        print(f"Finished {func.__name__} with result={result}")
        return result
    return wrapper

@log
def my_function(x, y):
    return x + y

my_function(1, 2)
python
Calling my_function with args=(1, 2), kwargs={}
Finished my_function with result=3

Timing

Penggunaan umum lain untuk decorator adalah mengukur berapa lama fungsi memakan waktu untuk dieksekusi. Ini dapat berguna untuk mengidentifikasi fungsi yang lambat atau tidak efisien. Berikut adalah contoh timing decorator:

python
import time

def timeit(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start:.2f} seconds")
        return result
    return wrapper

@timeit
def my_function():
    time.sleep(1)

my_function()
python
my_function took 1.00 seconds

Caching

Penggunaan umum ketiga untuk decorator adalah menyimpan hasil fungsi dalam cache untuk meningkatkan performa. Ini dapat berguna untuk fungsi yang memakan banyak waktu komputasi atau membutuhkan operasi I/O yang mahal. Berikut adalah contoh caching decorator:

python
def cache(func):
    cached_results = {}

    def wrapper(*args):
        if args in cached_results:
            return cached_results[args]
        result = func(*args)
        cached_results[args] = result
        return result

    return wrapper

@cache
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(30))
python
832040

Authentication

Penggunaan umum keempat untuk decorator adalah menerapkan persyaratan autentikasi atau otorisasi untuk fungsi. Ini dapat berguna untuk melindungi fungsi yang sensitif atau untuk mengontrol akses ke resource. Berikut adalah contoh authentication decorator:

python
def requires_authentication(func):
    def wrapper(*args, **kwargs):
        if not is_authenticated():
            raise Exception("Not authenticated")
        return func(*args, **kwargs)
    return wrapper

@requires_authentication
def my_function():
    # This function requires authentication
    pass

Referensi

https://www.geeksforgeeks.org/decorators-in-python/
https://peps.python.org/pep-0318/

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!