Menguasai Decorator Python: Tingkatkan Fungsi dengan Teknik Ahli
Python Decorators
Decorator memungkinkan Anda membungkus fungsi dengan logika yang dapat digunakan kembali, membuat kode Anda lebih modular, terbaca, dan mudah dipelihara. Dalam panduan ini kami membangun, menjelaskan, dan menerapkan decorator dalam skenario dunia nyata.
Video: @Decorators in Python
Decorators in Python
Decorator Python adalah alat metaprogramming yang kuat yang memungkinkan Anda menambah perilaku pada fungsi atau kelas pada saat definisi. Karena semuanya di Python adalah objek—termasuk fungsi dan kelas—decorator bekerja dengan mengambil satu callable, membungkusnya dalam yang lain, dan mengembalikan callable baru.
Prerequisites for Learning Decorators
Sebelum menyelami, Anda harus nyaman dengan fakta bahwa di Python, fungsi adalah first-class objects. Nama hanyalah referensi yang terikat pada objek; fungsi yang sama dapat direferensikan oleh banyak nama.
def first(msg):
print(msg)
first("Hello")
second = first
second("Hello")
Output
Hello Hello
Fungsi dapat diteruskan sebagai argumen, dikembalikan dari fungsi lain, dan bahkan bersarang di dalam fungsi lain. Konsep ini—higher-order functions, nested functions, dan closures—adalah blok pembangun decorator.
def inc(x):
return x + 1
def dec(x):
return x - 1
def operate(func, x):
result = func(x)
return result
Usage:
>>>>> operate(inc,3)
4
>>>>> operate(dec,3)
2
def is_called():
def is_returned():
print("Hello")
return is_returned
new = is_called()
new()
Output
Hello
Memahami closures adalah kunci: nested function mempertahankan akses ke cakupan enclosing, yang merupakan apa yang dieksploitasi decorator untuk menyimpan metadata atau memodifikasi perilaku.
Getting Back to Decorators
Di Python, decorator hanyalah callable yang menerima fungsi (atau callable lain) dan mengembalikan callable baru. Fungsi yang dikembalikan biasanya membungkus aslinya, menambah atau mengubah fungsionalitas sebelum atau setelah pemanggilan.
def make_pretty(func):
def inner():
print("I got decorated")
func()
return inner
def ordinary():
print("I am ordinary")
Example usage:
>>>>> ordinary()
I am ordinary
>>>>> pretty = make_pretty(ordinary)
>>>>> pretty()
I got decorated
I am ordinary
Decorator pattern menjaga semantik fungsi asli tetap utuh sambil melengkapinya. Untuk menghindari assignment manual, Python menyediakan syntactic sugar dengan simbol @:
@make_pretty
def ordinary():
print("I am ordinary")
Ini setara dengan:
def ordinary():
print("I am ordinary")
ordinary = make_pretty(ordinary)
Decorating Functions with Parameters
Banyak decorator harus menangani argumen sembarang. Sintaks *args dan **kwargs memungkinkan Anda menangkap argumen posisi atau kata kunci apa pun dan meneruskan mereka tanpa perubahan.
def works_for_all(func):
def inner(*args, **kwargs):
print("I can decorate any function")
return func(*args, **kwargs)
return inner
Menangani kasus tepi adalah use-case lain yang umum untuk decorator. Misalnya, melindungi dari pembagian dengan nol:
def smart_divide(func):
def inner(a, b):
print("I am going to divide", a, "and", b)
if b == 0:
print("Whoops! cannot divide")
return
return func(a, b)
return inner
@smart_divide
def divide(a, b):
print(a/b)
Usage:
>>>>> divide(2,5)
I am going to divide 2 and 5
0.4
>>>>> divide(2,0)
I am going to divide 2 and 0
Whoops! cannot divide
Chaining Decorators in Python
Decorator dapat ditumpuk. Urutan aplikasi penting, karena setiap decorator menerima fungsi yang dikembalikan oleh yang di bawahnya.
def star(func):
def inner(*args, **kwargs):
print("*" * 30)
func(*args, **kwargs)
print("*" * 30)
return inner
def percent(func):
def inner(*args, **kwargs):
print("%" * 30)
func(*args, **kwargs)
print("%" * 30)
return inner
@star
@percent
def printer(msg):
print(msg)
Result:
****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Hello %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ******************************
Membalik urutan menukar pola di sekitarnya, menunjukkan bagaimana tumpukan decorator mempengaruhi perilaku.