سلام دوستان
با ادامه ی کتاب پایتون مقدماتی که به همراه دوست عزیزم جناب مهندس مهدی عباسپور شاهمرس نوشته و چاپ کردیم در خدمتتون هستیم.
هر تابع متشکل از بلوک کدهای سازماندهیشده، با قابلیت استفادهی مجدد است که جهت انجام عملیات مرتبط و منسجم استفاده میشود. این توابع، برای برنامهها، حالت ماژولی و امکان استفادهی مجدد بهتری از کد را فراهم میکنند.
همان طوری که از قبل میدانیم، با وجود این که پایتون، توابع داخلی زیادی را در اختیار ما قرار میدهد، همچنان نیازمند تعریف توابع دلخواه بر حسب نیازهای متفاوت هستیم که در اصطلاح، آنها را توابع تعریفشده توسطکاربر[1] مینامیم.
[1]User-defined Functions
دانستیم که توابع میتوانند بر حسب نیازهای مختلف، تعریفشوند. در این بخش، قواعد سادهی تعریف یک تابع در پایتون را توضیح خواهیمداد.
شمای کلی تعریف یک تابع را در شکل (14-1) مشاهده میکنید.
لازم به ذکر است که، به طور پیش فرض، رفتار پارامترها برحسب مکان آنها، متغییر است. شما بایستی از آنها به همان ترتیبی که نوشتهاید، استفاده کنید. این امر بیشتر در صدا زدن توابع، کاربرد دارد. برای درک بهتر مطلب، در شکل (14-2)، تابع ما، یک رشته را به عنوان پارامتر ورودی گرفته و آن را چاپ میکند.
بعد از این که ایجاد یک تابع، به پایان رسید، میتوان آن را به صورت مستقیم ویا از درون توابع دیگر فراخوانیکرد. همان گونه که در شکل (14-3) میبینید، فقط با استفاده از نام تابع و مقداردهی پارامترها، میتوان آن را فراخوانیکرد. ما در این مثال، تابع تعریفشده در شکل (14-2) را صدا میزنیم.
با توجه به مقدار بازگشتی تابع printme، خروجی ما به شکل (14-4) خواهدبود.
در زبان پایتون، تمام پارامترها (آرگومانها)، توسط مرجع ارسال میشوند. به عبارت دیگر، اگر در چیزی که یک پارامتر به درون تابع ارجاع میدهد، تغییری ایجادکنیم، این تغییر در مقادیر فراخوانیکننده نیز تاثیر دارد. این مطلب را در مثال شکل (14-5) نشاندادیم.
همان طوری که در شکل (14-6) میبینید، ابتدا، لیست myList به تابع ارسالشده و در داخل تابع، مقادیری به آن افزودهشده و در نهایت چاپ میشود. این تغییر لیست، به دستور چاپِ خارج از تابع نیز اعمال میگردد. در نتیجه هر دو دستور چاپ، مقادیر یکسانی را در خروجی تولید میکنند.
شکل (14-7)، مثال دیگری را به نمایش میگذارد که در آن آرگومانها به صورت ارجاعی، فرستادهشده و این ارجاع در داخل تابع، بازنویسی میشود.
در این مثال، پارامتر mylist به صورت محلی در تابع changeme تعریف شدهاست. در نتیجه، تغییر در لیست داخل تابع، در لیست اصلی تاثیری نمیگذارد. در نهایت، خروجی ما به شکل (14-8) میشود. سطر اول خروجی، نتیجهی اجرای تابع و سطر دوم نتیجهی دستور چاپ خارج از تابع است.
[1]Pass by reference vs value
شما میتوانید یک تابع را با استفاده از این چهار نوع آرگومان رسمی، فرخوانیکنید:
14-4-1- آرگومانهای ضروری
همان طوری که از نامش پیداست، برای این که توابع ما، به صورت صحیح و بدون خطا کارکنند، باید این آرگومانها ارسالشوند. البته تعداد و ترتیب آنها در زمان ارسال بایستی با تعداد و ترتیب پارامترهای تعریفشده در تابع، مطابقت داشتهباشد. در شکل (14-9)، ما هیچ آرگومانی را برای تابع printme ارسالنکردیم.
خروجی این مثال را در شکل (14-10) میبینید. به دلیل عدم ارسال این پارامتر ضروری، با یک خطای نحوی روبرو میشویم.
14-4-2- آرگومانهای کلمهکلیدی
این آرگومانها، در زمان فراخوانی توابع، تعریف و مقداردهی میشوند. زمان استفاده از آنها، هر آرگومانی، با نام خودش، شناسایی میشود. این کار به ما اجازه میدهد تا تعدادی از آرگومانها را حذفکرده ویا آنها را خارج از ترتیب واردکنیم. مترجم پایتون قادر است برای تطبیق مقادیر پارامترها از کلماتکلیدی ارائهشده استفادهنماید. به عنوان مثال، میتوان تابع printme را به صورت شکل (14-11) فراخوانینمود.
برای درک بهتر این مطلب، از مثال دیگر در شکل (14-12) استفاده میکنیم. در حالی که هیچ ترتیبی در ارسال مقادیر پارامترها رعایت نشدهاست، برنامهی ما، بدون خطا کار میکند.
14-4-3- آرگومان پیشفرض
اگر هیچ مقداری برای این نوع آرگومانها اختصاصندهیم، تابع مدنظر، از مقادیر پیش فرض استفاده میکند. با نگاهکردن به مثال شکل (14-13) درمییابیم که بعد از تعریف تابع، یک بار آن را با مقداردهی همهی پارامترها، فراخوانیکرده و بار دیگر تنها با مقداردهی یکی از آنها، اقدام به فراخوانیکردیم.
بنابراین به دلیل عدم ارسال آرگومان age در فراخوانی تابع، برای دستور چاپدوم، از مقدار پیش فرض آن، یعنی 33 استفاده میشود. خروجی این مثال به شکل (14-14) خواهدبود.
14-4-4- آرگومانهایی با طولمتغیر
گاهی نیازمند استفاده از آرگومانهای بیشتر از تعداد تعریفشده برای تابع، باشیم. در این حالت، آرگومانهایی با طول متغیر را خواهیمداشت. برخلاف آرگومانهای نوع پیش فرض و کلمه کلیدی، در زمان تعریف تابع، ضرورتی برای اعلام و مقداردهی آنها نخواهیمداشت. شمای کلی این نوع آرگومانها به صورت شکل (14-15) است.
در این حالت، قبل از نام متغیر، یک علامت ستاره قرار میگیرد. این متغیر، مقادیر تمام آرگومانهای غیرکلیدی را در خود نگه میدارد. در صورتی که در زمان فراخوانی تابع، هیچ آرگومان اضافی، نیاز نباشد، مقدار این متغیر، خالی در نظرگرفته میشود. در شکل (14-16) سعیکردیم، یک مثال ساده از این نوع را به شما نشاندهیم.
خروجی اجرای این قطعه کد، به شکل (14-17) خواهدبود.
از آن جایی که برای تعریف این توابع، از کلمهی def استفادهنشده و ساختار آنها با توابع استاندارد یکسان نیست، نام ناشناس بر روی آنها گذاشتیم. برای تعریف یک تابع کوچک از این نوع، میتوانیم از کلمه کلیدی lambda استفادهکنیم. در ادامه، به ذکر چندین نکته در رابطه با تعریف چنین توابعی میپردازیم.
شمای کلی توابع لامبدا، به صورت شکل (14-18) خواهدبود. مثال شکل (14-19)، نمونهای از تعریف و فراخوانی این نوع توابع را نشان میدهد.
خروجی اجرای این قطعه کد، به شکل (14-20) است. همان گونه که مشاهده میکنید، هیچ نیازی به ورود مقادیر همهی آرگومانها در این توابع نیست.
[1]The Anonymous Functions [2]NameSpace [3]Global
گاهی متغیرهای مختلف یک برنامه، در تمامی بخشهای آن، در دسترس نیستند. این مطلب بستگی به مکانی دارد که شما آن متغیر را تعریف میکنید. به عبارت دیگر، حوزهی یک متغیر مشخص میکند که شما از کدام قسمت برنامه میتوانید به یک متغیر خاص، دسترسی داشتهباشید. در پایتون دو حوزهی اصلی به نام متغیرهای سراسری[2] و محلی برای متغیرها وجود دارد که در ادامه، به مقایسه و بررسی آنها میپردازیم.
متغیرهایی که داخل بدنهی تابع تعریف شدهاند را متغیرهای محلی و آنهایی که در خارج از بدنه تعریف میشوند را متغیرهای سراسری (جهانی) مینامیم. بنابراین متغیرهای محلی، فقط در داخل تابعی که در آن تعریف شدهاند، قابل دسترسی هستند. در حالی که، متغیرهای سراسری را میتوان در بخشهای مختلف برنامه و توسط هر تابعی به کار برد. همچنین زمانی که تابعی فراخوانی میشود، متغیرهای درون آن، در دسترس قرارگرفته و بعد از فراخوانی، از دسترس خارج میشوند. در شکل (14-21) مثال سادهای را در این رابطه آوردهایم.
اولین متغیر total که در ابتدای برنامه تعریف و مقدار صفر به آن انتصاب دادهشد، از نوع عمومی است. اما متغیر total دوم که درون بدنهی تابع تعریف و استفادهگردید، محلی است. از این رو، اثر تغییرات آن در خط آخر این قطعه کد (دستور چاپ)، اعمالنشد. در نهایت خروجی این مثال را در شکل (14-22) می بینید.
[1]Scope of Variables [2]Global variables
در پست بعدی به ماژول خواهیم پرداخت. با ما همراه باشین.