درک ساده دکوراتورها در پایتون

دکوراتورها مفهوم خیلی ساده و در عین حال کاربردی هستند که مثلا اگه با فلسک کار بکنید حتما نیاز خواهید داشت که ازش استفاده بکنید. البته با وجود اینکه دکوراتورها خیلی ساده هستند اما بعضیا واقعا درک‌ش نمی‌کنند!

خب ایده اینه که بتونیم از طریق یک تابع، کارکرد یک تابع دیگه رو تغییر بدیم و یا بهتر بگیم که یه تابع رو گسترش بدیم.

تصور کنید تابع ۱ رو دارید و تابع ۲ … حالا می‌خواید از طریق تابع ۱، کاری بکنید که تابع ۲ کارهای بیشتری رو انجام بده.

بیایید یه مثال ساده رو در نظر بگیریم:

تصور کنید من یه تابع دارم به اسم style که هر متنی که واردش بشه رو به صورتی زیبا برمی‌گردونه!

تصور کنید یه تابع دیگه هم دارم که متن رو چاپ می‌کنه. حالا می‌خوام بجای اینکه پروسه چاپ متن ساده انجام بشه، از قدرت تابع style برای این کار استفاده بکنم.

پس نیاز است که تابع style به عنوان ورودی یک تابع دیگر رو بگیره:

def style(func1):
print('--------------------')
func1()
print('--------------------')

حالا تابع دوممون رو که فقط قراره یه متن ساده رو چاپ بکنه تعریف می‌کنیم:

def print_some_text():
print(&quotHello World&quot)

حالا نیاز هست که تابع دوم رو به عنوان آرگومان برای تابع اولمون تعیین کنیم:

style(print_some_text)

قضیه علامت @ چیه؟

این شد یه چیزی! پایتون یه میانبر ساده برامون ایجاد کرده که از طریق اون می‌تونیم بدون فراخوانی قسمت آخر، دکوراتور رو اعمال بکنیم. برای اینکار کافیه قبل از تعریف تابع دومی @ را همراه با نام تابع اولی بنویسید:

@style

def print_some_text():
print(&quotHello World&quot)


print_some_text()

حالا یه مشکل پیش میاد. تابع اصلی که نوشتیم یا همون style یه بخش مهمی نداره! قسمت return … اینطوری یه تایپ ارور می‌گیریم چرا که تابع مقدار NoneType رو برمی‌گردونه! برای این کار می‌تونیم یه تابع دیگه داشته باشیم که اون تابع کارهای استایل دهی رو انجام می‌ده و در نهایت تابع style همون تابع رو برمی‌گردونه. برای این کار به تعریف تابع style برمی گردیم و مثل زیر ویرایشش می‌کنیم:

def style(func1):
def final():
print('------------')
func1()
print('------------')

return final

حالا کد رو اجرا کنید متوجه می‌شید که همه چیز بدون مشکل اجرا میشه!

برای مطالعه بیشتر همراه با مثال‌های دیگه می‌تونید این لینک رو بخونید.