ویرگول
ورودثبت نام
امیرحسین ناظوری
امیرحسین ناظوری📕 عاشق یادگیری و به اشتراک‌گذاری دانش -- آیدی من تو شبکه های اجتماعی : mrNazouri13
امیرحسین ناظوری
امیرحسین ناظوری
خواندن ۴ دقیقه·۹ ماه پیش

دکوراتور (Decorator) ها در پایتون

سلام رفقا. حالتون چطوره؟ امیرحسین ناظوری هستم و خوش اومدید به یکی دیگه از نوشته هام داخل ویرگول. اینجا قراره راجب دکوراتور ها (Decorators) آموزش ببینیم.

دکوراتور (Decorator) چیه؟
دکوراتورها تو پایتون یه جور تابع خاصی هستن که می‌تونی باهاش یه تابع دیگه رو تزئین کنی یا بهش یه قابلیت اضافه بکنی بدون اینکه کد تابع اصلی تغییر کنه.

یه مثال میزنم بهتر درک کنید ! من یک تابع دارم که وقتی صدا زده میشه مقدار Amirhosein رو چاپ میکنه. از طرفی یک تابع دیگه هم دارم که وقتی اون صدا زده میشه مقدار Arta رو چاپ میکنه. کد :

def print_amirhosein(): print('Amirhosein')
def print_arta(): print('Arta')

این توابع خیلی ساده میان اون عبارت رو print میکنن. حالا من میخوام قبل و بعد از اسم ها چندتا ستاره (*) چاپ بشه. یعنی اول 20 تا ستاره print بشه و بعد عبارت رو چاپ کنه و درآخر دوباره 20 تا ستاره print بشه. تو حالت سادش من باید بیام کد رو به شکل زیر تغییر بدم :

def print_amirhosein(): print('*' * 20) print('Amirhosein') print('*' * 20)
def print_arta(): print('*' * 20) print('Arta') print('*' * 20)

اما چرا تا وقتی Decorator ها وجود دارن باید بدین شکل کار کنم؟ به کد زیر دقت کن :

تو این کد برای نمایش ستاره ها تغییری در کد اصلی تابع ها ایجاد نکردم !
تابع print_star همون دکوراتور هست. این تابع یک ورودی رو دریافت میکنه که بعدا میفهمیم چرا. داخل print_star یک تابع دیگه ساختم به اسم inner که میاد ابتدا 20 تا ستاره رو print میکنه و سپس func که ورودی دکوراتور هست رو صدا میزنه و جلوش پرانتز قرار میده ! من برای ورودی دکوراتور باید تابع print_amirhosein و print_arta رو بدم، این دکوراتور میاد ستاره هارو چاپ میکنه، سپس تابعی که موقع صدا زدن بهش دادم رو فراخانی میکنه که مثلا میاد عبارت amirhosein رو print میکنه، درآخر مجدد 20 تا ستاره دیگه رو چاپ میکنه. و اینطوری هست که بدون تغییر در کد اصلی تابع میتونم ستاره هارو قبل و بعد از اسم ها print کنم. در آخر اومدم تابع inner رو return کردم و تو خط های آخر چون تابع inner برگشت خورده، خروجی رو داخل یک متغییر ذخیره کردم، بعد اون متغییر رو (که یک تابع هست) صدا میزنم و پرانتز رو جلوش قرار میدم تا function اجرا بشه. (اگه متوجه نشدید ویدیو مربوطه رو داخل یوتیوبم برید ببینید)
البته به شکل زیر هم میشه استفاده کرد :

من بجای اینکه بخوام inner رو return کنم و خروجی رو در یک متغییر دیگه ذخیره کنم، میام inner رو صدا میزنم و خروجی زیر بهم برمیگرده :

(البته اگه بخوام تابع رو جاهای دیگه و چند بار استفاده کنم بهتره return کنم چرا که بتونم داخل یک متغییر ذخیره بکنمش)

یه نکته. این روشی که ما از دکوراتور استفاده میکنیم درست نیست ! یعنی اینکه بیایم تابع print_star رو صدا بزنیم و بهش ورودی رو بدیم. میدونی روش درست چیه ؟ آفرین. استفاده از @ هست. به کد زیر دقت کن.

خروجی :

من فقط کافیه بیام @ رو قبل از تابع مدنظرم بزارم و اسم تابعی که به عنوان دکوراتور ساخته شده رو بنویسم. وقتی من تو خط 298 نوشتم @print_star یعنی تمام مراحل قبلی انجام شد، اومد تابع print_star رو صدا زد، تابع print_amirhosein رو به عنوان ورودی بهش داد، ابتدا 20 تا ستاره print کرد، بعد تابع print_amirhosein رو فراخانی کرد و دوباره 20 تا ستاره print کرد. تو این حالت من کافیه اسم تابع اصلی رو بنویسم و تمام اون تغییرات روش انجام میشه (به واسطه علامت @)
حالا اگه دقت کنین من از print_star@ برای تابع print_arta استفاده نکردم و به همین دلیل دکوراتور روی اون فراخانی نشد و همون عبارت Arta رو بصورت ساده print کرد.

یه خبر خوب.
میخوام یه تمرین باهم انجام بدیم که مطمئن بشم 100% موضوع دکوراتور هارو متوجه شدید.
تمرین چیه ؟ یک تابعی وجود داره که دوتا عدد رو میگیره و تقسیم میکنه، حالا همینطور که در جریانید اگه عددی بخواد تقسیم به 0 بشه خطا میده و این اتفاق نمیوفته. حالا میخوام یک دکوراتور ایجاد کنم که بیاد بررسی کنم آیا عدد دوم 0 هست یا نه. اگه 0 بود نزاره تابع اصلی اجرا بشه و خطایی رخ نده. کد :

وقتی من از mohasebe@ استفاده کردم و بعدش اومدم taghsim رو صدا زدم، درواقع اینجا تابع taghsim اجرا نمیشه، بلکه inner اجرا میشه و هرچیزی که داخل اون تابع وجود داشته باشه فراخان میشه.

برنامه نویسیپایتون
۳
۰
امیرحسین ناظوری
امیرحسین ناظوری
📕 عاشق یادگیری و به اشتراک‌گذاری دانش -- آیدی من تو شبکه های اجتماعی : mrNazouri13
شاید از این پست‌ها خوشتان بیاید