လွယ်လွယ်ပြောရင် decorator ဆိုတာ function တစ်ခုကို သူ့ရဲ့ code ကို မထိဘဲ — အပြင်ကနေ “အထုပ်” ထပ်ရွက်လိုက်သလို အပြုအမူ အသစ် ထပ်ထည့်တဲ့ Python နည်းပညာပါ။ @ သင်္ကေတနဲ့ function အပေါ်မှာ ရေးတယ်။
လက်ဆောင် အထုပ်ရွက်တာ ဥပမာနဲ့ ပြောရအောင်။ သင့်မှာ စာအုပ်တစ်အုပ် ရှိတယ် — ဒါက မူလ function။ သူ့ကို လက်ဆောင်ပေးချင်လို့ အထုပ်ရွက်လိုက်တယ် — စာအုပ်က အတူတူပဲ၊ ဒါပေမယ့် အပြင်မှာ ဖဲကြိုးနဲ့ ကတ်ပြားနဲ့ ဖြစ်သွားပြီ။ Decorator က ဒီလိုပဲ — မူလ function ရဲ့ code ကို မထိဘဲ သူ့အပြင်မှာ အလွှာတစ်ခု ထပ်အုပ်လိုက်တာ။ အထဲမှာ အလုပ်လုပ်တာက မူလ function အတိုင်းပဲ၊ ဒါပေမယ့် အပြင်က အလွှာက အပို အလုပ် (ဥပမာ အချိန်တိုင်းတာ၊ login စစ်တာ) လုပ်ပေးတယ်။
တကယ့် code နဲ့ ကြည့်ရအောင်။ Function တစ်ခု run တာ ဘယ်လောက် ကြာလဲ တိုင်းချင်တယ်ဆိုပါတော့ —
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
print("ကြာချိန်:", time.time() - start, "စက္ကန့်")
return result
return wrapper
@timer
def add(a, b):
return a + b
add(3, 5) # ကြာချိန်ပါ ပြပေးမယ်
ဒီမှာ @timer ဆိုတာက add = timer(add) လို့ ရေးတာနဲ့ အတူတူပဲ။ timer က add ကို ယူတယ်၊ wrapper ဆိုတဲ့ function အသစ် ပြန်ပေးတယ်။ add(3, 5) လို့ ခေါ်လိုက်တိုင်း တကယ်က wrapper(3, 5) run နေတာ — wrapper က အချိန်မှတ်တယ်၊ ပြီးမှ မူလ add ကို ခေါ်တယ်၊ အဖြေကို ပြန်ပေးတယ်။
နေ့တိုင်း တွေ့နေတဲ့ ဥပမာတွေ —
Flask မှာ @app.route("/home") — ဒီ decorator က function ကို website ရဲ့ /home လမ်းကြောင်းနဲ့ ချိတ်ပေးတယ်@login_required — Django/Flask app တွေမှာ login ဝင်ပြီးသားလူပဲ ဒီ page ကြည့်လို့ရအောင် လုပ်တာ@lru_cache — Python ရဲ့ functools ထဲက decorator၊ function ရဲ့ အဖြေဟောင်းတွေ မှတ်ထားပြီး ထပ်မတွက်ဘူး (cache လုပ်တာ)@staticmethod, @classmethod — class ထဲမှာ သုံးတဲ့ built-in decorator တွေ
ကိုယ်တိုင် ရေးကြည့်ချင်ရင် —
အရင်ဆုံး decorator မပါဘဲ function ရိုးရိုး ရေးကြည့်
ပြီးမှ အပေါ်မှာ @timer ထည့်ပြီး run ကြည့် — code တစ်ကြောင်းမှ မပြောင်းဘဲ အပြုအမူ အသစ် ရလာတာ တွေ့ရမယ်
Decorator မှာ argument ပေးချင်ရင် decorator factory (decorator ကို ပြန်ပေးတဲ့ function) သုံးရတယ် — နည်းနည်း ရှုပ်တယ်၊ နောက်မှ လေ့လာပါfunctools.wraps ကို wrapper ထဲမှာ သုံးပါ — မဟုတ်ရင် မူလ function ရဲ့ နာမည်ပျောက်သွားတတ်တယ်
Decorator ကို နားလည်သွားရင် Flask, Django လို framework တွေရဲ့ code တွေ ဖတ်ရတာ အများကြီး လွယ်သွားမယ်။ @ လေး တစ်လုံးက code အများကြီးကို သပ်သပ်ရပ်ရပ် ထိန်းပေးထားတာ — လက်ဆောင် အထုပ်လှလှလေးလိုပေါ့။ 🙂