Decorator
Pada artikel ini, kita akan pelajari mengenai decorator, langkah membuat decorator, dan kapan kita seharusnya memakai decorator.
Pengertian Decorator
Python mempunyai sebuah feature menarik namanya decorator yang berperan menambahkan fungsionalitas pada code program.
Ini disebutkan metaprogramming karena ada sisi dari program yang berusaha untuk melakukan modifikasi sisi yang lain di saat eksekusi.
Syarat Sebelum Mempelajari Decorator
Saat sebelum bisa pahami mengenai decorator, kita harus lebih dulu pahami dasar - dasar Python.
Kita harus memahami lebih dulu jika semuanya yang berada di Python ialah object (terhitung kelas). Nama pengenal, seperti faktor yang kita maklumatkan mengarah ke object itu. Begitupun dengan peranan. Peranan ialah terhitung object juga. Satu object dapat banyak memiliki pengenal (identifier) yang mengarah padanya.
Perhatikan contoh berikut
script.py
IPython Shell
Powered by DataCamp
Di saat code di atas digerakkan, ke-2 peranan first dan second tampilkan output yang serupa. Di sini, faktor first dan second mengarah pada object peranan yang serupa.
Saat ini silahkan kita evaluasi hal lainnya. Sebuah peranan dapat dijadikan argument dari peranan lainnya.
Jika Anda pernah memakai peranan seperti map, filter, dan reduce di Python, karena itu Anda sudah mengetahui mengenai ini.
Peranan yang jadikan peranan lain sebagai argument disebutkan peranan dengan orde yang semakin tinggi. Berikut misalnya:
script.py
IPython Shell
Powered by DataCamp
Kita dapat panggil peranan itu sebagai berikut:
>>> operate(inc, 3)
4
>>> operate(dec, 3)
2
Lebih kembali berlanjut, sebuah peranan bisa mengembalikan fungsi lain.
script.py
IPython Shell
Powered by DataCamp
Pada contoh itu, is_returned() ialah peranan bersarang yang diartikan dan dibalikkan setiap kali peranan is_called() diundang.
Selainnya pahami mengenai hal di atas, kita harusnya memahami mengenai python closure
Kembali lagi ke Decorator
Sebuah decorator ambil peranan sebagai argument-nya, menambah banyak hal, dan mengembalikannya.
script.py
IPython Shell
Powered by DataCamp
Jika code di atas kita lakukan pada model interaktif, karena itu hasilnya ialah sebagai berikut:
>>> ordinary()
I am ordinary
>>> # Silahkan kita bikin decorator dari peranan ordinary
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary
Pada contoh di atas, make pretty() ialah sebuah decorator.
Pada baris perintah pretty = make_pretty(ordinary), peranan ordinary dihiasi dan peranan kembaliannya dinamakan pretty.
Kita dapat saksikan jika peranan decorator menambah beberapa fungsionalitas ke peranan asli. Ini serupa dengan pengepakan hadiah. Decorator bertindak selaku buntelnya. Object yang dihiasi (isi hadiah) tetap sama. Namun, saat dibuntel, akan kelihatan lebih baik (karena dihiasi).
Biasanya, kita membuat dekorasi peranan dan menyimpan ke faktor sebagai berikut:
ordinary = make_pretty(ordinary)
Python mempunyai sintaks yang lebih simpel untuk penulisan peranan di atas yakni dengan memakai pertanda @ dituruti oleh nama peranan decorator. Kita meletakkannya di atas peranan yang bakal dihiasi. Karena itu contoh berikut:
@make_pretty
def ordinary():
print("I am ordinary ")
ialah sama yang berikut ini:
def ordinary():
print("I am ordinary ")
ordinary = make_pretty(ordinary)
Langkah yang memakai pertanda @ di atas ialah sintaks yang lebih menawan untuk menerapkan decorator.
Dekorasi Fungsi Dengan Parameter
Decorator di atas benar-benar simpel dan cuman berlaku untuk peranan yang tidak mempunyai patokan. Bagaimana bila peranan yang bakal dihiasi mempunyai argument sebagai berikut?
def divide(a, b):
return a/b
Peranan itu mempunyai 2 patokan, a dan b. Jika kita melewati nilai 0 ke b, maka terjadi error ZeroDivisionError.
>>> divide(2, 5)
0.4
>>> divide(2, 0)
Traceback (most recent call last):
...
ZeroDivisionError: divisi by zero
Saat ini kita akan membuat decorator untuk memeriksa pemicu error ini.
script.py
IPython Shell
Powered by DataCamp
Code yang memakai decorator ini akan kembalikan None bila terjadi error.
>>> divide(2, 5)
Saya akan membagikan 2 dan 5
0.4
>>> divide(2, 0)
Saya akan membagikan 2 dan 0
Whoops! tidak dapat membagikan dengan 0
Dengan itu kita dapat membuat dekorasi peranan yang mempunyai patokan.
Jika kita lihat secara baik, kita akan menyaksikan jika semua patokan dari peranan yang dalam decorator bisa menjadi patokan dari peranan yang dihiasi. Dengan itu, kita dapat membuat decorator yang lebih umum yang bisa bekerja dengan berapa saja jumlah patokannya.
Di Python, ini bisa dilaksanakan dengan sintaks function(*args, **kwargs) di mana args ialah tuple dari argument - argument berdasar status, dan kwargs ialah dictionary dari argument - argument ber-keyword.
Berikut ialah contoh peranan inner() yang mempunyai sembarangan patokan dihiasi oleh peranan works_for_all().
def works_for_all(func):
def inner(*args, **kwargs):
print("Saya dapat membuat dekorasi peranan apa ")
return func(*args, **kwargs)
return inner()
Menggabungkan Decorator di Python
Beberapa decorator dapat disambungkan atau dipadukan. Sebuah peranan dapat dihiasi seringkali dengan 1 atau fungsi-fungsi decorator. Kita menempatkan decorator di atas peranan yang bakal dihiasi. Untuk terangnya lihat contoh berikut ini:
script.py
IPython Shell
Powered by DataCamp
Outputnya akan terlihat sebagai berikut:
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hello
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
Code decorator di atas yakni:
@star
@percent
def printer(msg):
print(msg)
ialah sama dengan:
def printer(msg):
print(msg)
printer = star(percent(printer))
Posisi dari decorator penting diingat. Jika kita mengganti posisinya jadi:
@percent
@star
def printer(msg):
print(msg)
karena itu hasilnya bisa menjadi:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
Hello
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%