فصل چهاردهم آموزش پایتون مقدماتی - توابع (انتشار: 1402/08/04)

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

این چیه؟

14-1- تعریف تابع

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

  • هر بلوک تابع با کلمه کلیدی def شروع‌‌شده و به دنبال آن، نام تابع و سپس علامت‌‌های پارانتز می‌‌آید.
  • پارامترها ویا آرگومان‌‌های ورودی باید در داخل این پارانتزها قرار‌‌گیرند.
  • اولین خط هر تابع می‌‌تواند یک عبارت اختیاری باشد که حاوی توصیفی از آن تابع است.
  • بلوک کد بایستی با علامت دو نقطه شروع‌‌شود. البته تمامی دستورات باید دارای تورفتگی باشند.
  • دستور return [expression] موجب خروج ما از تابع می‌‌شود. عبارت اختیاری داخل علامت‌‌های براکت، یک مقدار را به صداکننده‌‌ی تابع بازمی‌‌گرداند. دستور return بدون آرگومان، معادل دستوری است که هیچ عبارت بازگشتی ندارد.

شمای کلی تعریف یک تابع را در شکل (14-1) مشاهده می‌‌کنید.

پایتون-شکل1-14

لازم به ذکر است که، به طور پیش فرض، رفتار پارامترها برحسب مکان آن‌‌ها، متغییر است. شما بایستی از آن‌‌ها به همان ترتیبی که نوشته‌‌اید، استفاده کنید. این امر بیشتر در صدا زدن توابع، کاربرد دارد. برای درک بهتر مطلب، در شکل (14-2)، تابع ما، یک رشته را به عنوان پارامتر ورودی گرفته و آن را چاپ می‌‌کند.

پایتون-شکل2-14

14-2- فراخوانی تابع

بعد از این که ایجاد یک تابع، به پایان رسید، می‌‌توان آن را به صورت مستقیم ویا از درون توابع دیگر فراخوانی‌‌کرد. همان گونه که در شکل (14-3) می‌‌بینید، فقط با استفاده از نام تابع و مقداردهی پارامترها، می‌‌توان آن را فراخوانی‌‌کرد. ما در این مثال، تابع تعریف‌‌شده در شکل (14-2) را صدا می‌‌زنیم.

پایتون-شکل3-14

با توجه به مقدار بازگشتی تابع printme، خروجی ما به شکل (14-4) خواهدبود.

پایتون-شکل4-14

14-3- ارسال پارامتر با مقدار و ارسال با مرجع

در زبان پایتون، تمام پارامترها (آرگومان‌‌ها)، توسط مرجع ارسال می‌‌شوند. به عبارت دیگر، اگر در چیزی که یک پارامتر به درون تابع ارجاع می‌‌دهد، تغییری ایجاد‌‌کنیم، این تغییر در مقادیر فراخوانی‌‌کننده نیز تاثیر دارد. این مطلب را در مثال شکل (14-5) نشان‌‌دادیم.

پایتون-شکل5-14

همان طوری که در شکل (14-6) می‌‌بینید، ابتدا، لیست myList به تابع ارسال‌‌شده و در داخل تابع، مقادیری به آن افزوده‌‌شده و در نهایت چاپ می‌‌شود. این تغییر لیست، به دستور چاپِ خارج از تابع نیز اعمال می‌‌گردد. در نتیجه هر دو دستور چاپ، مقادیر یکسانی را در خروجی تولید می‌‌کنند.

پایتون-شکل6-14

شکل (14-7)، مثال دیگری را به نمایش می‌‌گذارد که در آن آرگومان‌‌ها به صورت ارجاعی، فرستاده‌‌شده و این ارجاع در داخل تابع، بازنویسی می‌‌شود.

پایتون-شکل7-14

در این مثال، پارامتر mylist به صورت محلی در تابع changeme تعریف شده‌‌است. در نتیجه، تغییر در لیست داخل تابع، در لیست اصلی تاثیری نمی‌‌گذارد. در نهایت، خروجی ما به شکل (14-8) می‌‌شود. سطر اول خروجی، نتیجه‌‌ی اجرای تابع و سطر دوم نتیجه‌‌ی دستور چاپ خارج از تابع است.

پایتون-شکل8-14

14-4- آرگومان‌‌های تابع

شما می‌‌توانید یک تابع را با استفاده از این چهار نوع آرگومان رسمی، فرخوانی‌‌کنید:

14-4-1- آرگومان‌‌های ضروری

همان طوری که از نامش پیداست، برای این که توابع ما، به صورت صحیح و بدون خطا کار‌‌کنند، باید این آرگومان‌‌ها ارسال‌‌شوند. البته تعداد و ترتیب آن‌‌ها در زمان ارسال بایستی با تعداد و ترتیب پارامترهای تعریف‌‌شده در تابع، مطابقت داشته‌‌باشد. در شکل (14-9)، ما هیچ آرگومانی را برای تابع printme ارسال‌‌نکردیم.

پایتون-شکل9-14

خروجی این مثال را در شکل (14-10) می‌‌بینید. به دلیل عدم ارسال این پارامتر ضروری، با یک خطای نحوی روبرو می‌‌شویم.

پایتون-شکل10-14

14-4-2- آرگومان‌‌های کلمه‌‌کلیدی

این آرگومان‌‌ها، در زمان فراخوانی توابع، تعریف و مقداردهی می‌‌شوند. زمان استفاده از آن‌‌ها، هر آرگومانی، با نام خودش، شناسایی می‌‌شود. این کار به ما اجازه می‌‌دهد تا تعدادی از آرگومان‌‌ها را حذف‌‌کرده ویا آن‌‌ها را خارج از ترتیب وارد‌‌کنیم. مترجم پایتون قادر است برای تطبیق مقادیر پارامترها از کلمات‌‌کلیدی ارائه‌‌شده استفاده‌‌نماید. به عنوان مثال، می‌‌توان تابع printme را به صورت شکل (14-11) فراخوانی‌‌نمود.

پایتون-شکل11-14

برای درک بهتر این مطلب، از مثال دیگر در شکل (14-12) استفاده می‌‌کنیم. در حالی که هیچ ترتیبی در ارسال مقادیر پارامترها رعایت نشده‌‌است، برنامه‌‌ی ما، بدون خطا کار می‌‌کند.

پایتون-شکل12-14

14-4-3- آرگومان پیش‌‌فرض

اگر هیچ مقداری برای این نوع آرگومان‌‌ها اختصاص‌‌ندهیم، تابع مدنظر، از مقادیر پیش فرض استفاده می‌‌کند. با نگاه‌‌کردن به مثال شکل (14-13) درمی‌‌یابیم که بعد از تعریف تابع، یک بار آن را با مقداردهی همه‌‌ی پارامترها، فراخوانی‌‌کرده و بار دیگر تنها با مقداردهی یکی از آن‌‌ها، اقدام به فراخوانی‌‌کردیم.

پایتون-شکل13-14

بنابراین به دلیل عدم ارسال آرگومان age در فراخوانی تابع، برای دستور چاپ‌‌دوم، از مقدار پیش فرض آن، یعنی 33 استفاده می‌‌شود. خروجی این مثال به شکل (14-14) خواهدبود.

پایتون-شکل14-14

14-4-4- آرگومان‌‌هایی با طول‌‌متغیر

گاهی نیازمند استفاده از آرگومان‌‌های بیشتر از تعداد تعریف‌‌شده برای تابع، باشیم. در این حالت، آرگومان‌‌هایی با طول متغیر را خواهیم‌‌داشت. برخلاف آرگومان‌‌های نوع پیش فرض و کلمه کلیدی، در زمان تعریف تابع، ضرورتی برای اعلام و مقداردهی آن‌‌ها نخواهیم‌‌داشت. شمای کلی این نوع آرگومان‌‌ها به صورت شکل (14-15) است.

پایتون-شکل15-14

در این حالت، قبل از نام متغیر، یک علامت ستاره قرار می‌‌گیرد. این متغیر، مقادیر تمام آرگومان‌‌های غیرکلیدی را در خود نگه می‌‌دارد. در صورتی که در زمان فراخوانی تابع، هیچ آرگومان اضافی، نیاز نباشد، مقدار این متغیر، خالی در نظرگرفته می‌‌شود. در شکل (14-16) سعی‌‌کردیم، یک مثال ساده از این نوع را به شما نشان‌‌دهیم.

پایتون-شکل16-14

خروجی اجرای این قطعه کد، به شکل (14-17) خواهدبود.

پایتون-شکل17-14

14-5- توابع ناشناس

از آن جایی که برای تعریف این توابع، از کلمه‌‌ی def استفاده‌‌نشده و ساختار آن‌‌ها با توابع استاندارد یکسان نیست، نام ناشناس بر روی آن‌‌ها گذاشتیم. برای تعریف یک تابع کوچک از این نوع، می‌‌توانیم از کلمه کلیدی lambda استفاده‌‌کنیم. در ادامه، به ذکر چندین نکته در رابطه با تعریف چنین توابعی می‌‌پردازیم.

  • انواع مختلف لامبدا می‌‌تواند تعداد دلخواهی از آرگومان‌‌ها را داشته‌‌باشد، اما فقط یک مقدار را به صورت نمایش یک عبارت، برمی‌‌گرداند. آن‌‌ها قادر به برگرداندن دستورات و عبارات متعدد نیستند.
  • به دلیل این که، لامبدا نیازمند یک عبارت است، این توابع نمی‌‌توانند یک فراخوانی مستقیم را برای چاپ یک عبارت داشته‌‌باشد.
  • توابع لامبدا، فضای اسمی محلی مخصوص به خود را دارند و نمی‌‌توانند به غیر از متغیرهایی که برایشان فهرست شده‌‌است ویا آن‌‌هایی که در فضای اسمی عمومی قرار دارند، دسترسی پیدا‌‌کنند.
  • اگر چه به نظر می‌‌رسد که لامبدا نسخه‌‌ای از توابع تک خطی هستند، اما نمی‌‌توان آن‌‌ها را معادل این نوع توابع در زبان C ویا C++ درنظر گرفت. توابع تک خطی در زبان‌‌های ذکرشده، برای عبور دادن پشته‌‌ی توابع، برای بهبود کارایی در زمان فراخوانی استفاده می‌‌شوند.

شمای کلی توابع لامبدا، به صورت شکل (14-18) خواهدبود. مثال شکل (14-19)، نمونه‌‌ای از تعریف و فراخوانی این نوع توابع را نشان می‌‌دهد.

پایتون-شکل18-14
پایتون-شکل19-14

خروجی اجرای این قطعه کد، به شکل (14-20) است. همان گونه که مشاهده می‌‌کنید، هیچ نیازی به ورود مقادیر همه‌‌ی آرگومان‌‌ها در این توابع نیست.

پایتون-شکل20-14

14-6- حوزه‌‌ی متغیرها

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

متغیرهایی که داخل بدنه‌‌ی تابع تعریف شده‌‌اند را متغیرهای محلی و آن‌‌هایی که در خارج از بدنه تعریف می‌‌شوند را متغیرهای سراسری (جهانی) می‌‌نامیم. بنابراین متغیرهای محلی، فقط در داخل تابعی که در آن تعریف شده‌‌اند، قابل دسترسی هستند. در حالی که، متغیرهای سراسری را می‌‌توان در بخش‌‌های مختلف برنامه و توسط هر تابعی به کار برد. همچنین زمانی ‌‌که تابعی فراخوانی می‌‌شود، متغیرهای درون آن، در دسترس قرارگرفته و بعد از فراخوانی، از دسترس خارج می‌‌شوند. در شکل (14-21) مثال ساده‌‌ای را در این رابطه آورده‌‌ایم.

پایتون-شکل21-14

اولین متغیر total که در ابتدای برنامه تعریف و مقدار صفر به آن انتصاب داده‌‌شد، از نوع عمومی است. اما متغیر total دوم که درون بدنه‌‌ی تابع تعریف و استفاده‌‌گردید، محلی است. از این رو، اثر تغییرات آن در خط آخر این قطعه کد (دستور چاپ)، اعمال‌‌نشد. در نهایت خروجی این مثال را در شکل (14-22) می بینید.

پایتون-شکل22-14

 

در پست بعدی به ماژول خواهیم پرداخت. با ما همراه باشین.

 


نظرات خوانندگان نوشته


نظری در این مورد دارید؟ خوشحال می‌شیم اون رو برامون ارسال کنید.