Penghias dalam Python

Penghias dalam Python

Artikel ini menerangkan tentang penghias dalam Python.

YouTube Video

Penghias dalam Python

Penghias Python ialah ciri yang kuat yang digunakan untuk menambah fungsi tambahan kepada fungsi atau kaedah. Penghias membolehkan anda menambah fungsi baharu tanpa mengubah kod sedia ada, lantas meningkatkan penggunaan semula dan penyenggaraan kod.

Asas Penghias

Penghias Python berfungsi dengan mengambil fungsi sebagai argumen dan mengembalikan fungsi baharu dengan tambahan fungsi. Dengan penghias, anda boleh dengan mudah menambah pra-pemprosesan atau selepas-pemprosesan kepada fungsi.

Tanpa penghias, mengubah tingkah laku fungsi memerlukan pengeditan secara langsung pada fungsi itu sendiri. Dengan penghias, anda boleh meluaskan fungsi tanpa mengubah pelaksanaan asal.

Struktur Asas Penghias

 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 penghias yang membalut fungsi say_hello. Penghias digunakan dengan sintaks @my_decorator, dan apabila say_hello() dipanggil, pra- dan selepas-pemprosesan yang disediakan oleh penghias dijalankan secara automatik.

Bagaimana Penghias Berfungsi

Penghias berfungsi dalam langkah-langkah berikut.

  1. Penghias mengambil fungsi (atau kaedah) sebagai argumen.

  2. Ia mentakrifkan fungsi pembalut untuk melaksanakan fungsi asal.

  3. Fungsi pembalut melaksanakan pemprosesan tambahan sebelum atau selepas melaksanakan fungsi asal.

  4. Penghias mengembalikan fungsi pembalut. Hasilnya, fungsi asal digantikan dengan fungsi baharu yang dihias.

Penghias untuk Fungsi dengan Argumen

Apabila menggunakan penghias pada fungsi dengan argumen, fungsi pembalut mesti 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, adalah mungkin untuk mengendalikan fungsi yang menerima sebarang bilangan argumen dan argumen kata kunci. Ini membolehkan penghias digunakan secara umum pada fungsi dengan sebarang jenis argumen.

Contoh Penggunaan Penghias (Decorators)

Penghias untuk Catatan Log

Penghias sering digunakan untuk menambah fungsi log. Sebagai contoh, dengan mencipta penghias yang mencatat sebelum dan selepas pelaksanaan fungsi, anda boleh merekodkan bila fungsi dipanggil dan berapa lama masa yang diambil untuk dilaksanakan.

 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, penghias log_time mengukur masa pelaksanaan fungsi dan mengeluarkannya sebagai log. Fungsi long_task dibalut dengan penghias, dan masa pelaksanaannya direkodkan semasa masa jalanan (runtime).

Penghias untuk Pengurusan Kebenaran

Penghias juga boleh digunakan untuk pengurusan kebenaran. Sebagai contoh, anda boleh mengehadkan pemprosesan dengan memeriksa sama ada pengguna mempunyai kebenaran 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!

Penghias requires_permission mengehadkan pelaksanaan fungsi berdasarkan peranan pengguna. Dengan menyatukan logik sedemikian ke dalam penghias, anda boleh menghalang logik pengurusan kebenaran daripada berselerak di seluruh kod anda, sekaligus meningkatkan kebolehbacaan.

Penghias Bersarang

Adalah mungkin untuk menggunakan pelbagai penghias. Apabila pelbagai penghias digunakan pada satu fungsi, ia dilaksanakan mengikut susunan 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!"

Dalam contoh ini, dua penghias digunakan pada fungsi greet. Penghias @exclaim menambah tanda seru di hujung string, dan kemudian @uppercase menjadikan string menjadi huruf besar.

Penghias untuk Kaedah Kelas

Penghias juga boleh digunakan dengan kaedah kelas. Ini sangat berguna apabila anda ingin mengawal tingkah laku kaedah-kaedah dalam kelas. Apabila menggunakan penghias pada kaedah kelas, anda perlu memberi perhatian kepada 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, penghias log_method_call digunakan pada kaedah greet untuk mengeluarkan log apabila kaedah itu dipanggil.

Perhatian dengan Penghias

Terdapat beberapa perkara yang perlu dipertimbangkan apabila menggunakan penghias. Penghias boleh mengubah nama dan string dokumentasi fungsi asal (contoh, __name__ atau __doc__), jadi disarankan untuk menggunakan functools.wraps bagi mengekalkan maklumat 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

Menggunakan @functools.wraps memastikan metadata fungsi asal dipindahkan dengan betul ke fungsi pembalut.

Ringkasan

Penghias Python adalah alat yang sangat berkuasa yang membolehkan anda menambah fungsi tambahan kepada fungsi dan kaedah dengan ringkas. Ia boleh digunakan dalam pelbagai senario untuk mengurangkan penggandaan kod dan meningkatkan kebolehselenggaraan serta kebolehpenggunaan semula. Dengan memahami bagaimana penghias berfungsi, anda boleh menulis kod yang lebih cekap dan fleksibel.

Anda boleh mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Sila lihat juga saluran YouTube kami.

YouTube Video