توابع برنامههای کوچکی هستند که این قابلیت را دارند که در قسمتهای دیگر برنامه از آن استفاده کنید. برای استفاده از توابع از طریق نام گذاری تابع و فراخوانی آن میتوانید در دیگر قسمتهای برنامهها از این توابع استفاده کنید. به این روش فراخوانی تابع میگویند. در برنامههای قبلی از توابع داخلی پایتون استفاده کردیم مانند len
و range
.
ساختار مفهومی تابع احتمالا یکی از مهمترین بخشهای هر برنامهنویسی است. بنابراین در این فصل بخشهای مختلف تابع را بررسی خواهیم کرد.
تابع با استفاده از کلید واژهی def
تعریف میشود. بعد از این کلمهی کلیدی نام (شناسه) تابع و بعد از نام دو جفت پرانتز گذاشته میشود. داخل پرانتز ممکن است متغییری قرار بگیرد. سپس بلوک کدهای برنامه است. برای مثال:
برای مثال (فایلی با نام function1.py
ذخیره کنید)
برای مشاهده برنامهها بهتر است به لینک زیر سر بزنید:
{% include "./programs/function1.py" %}
خروجی:
{% include "./programs/function1.txt" %}
چگونه و چطوری
در بالا ما یک تابعی با نام say_hello
داریم این تابع هیچ پارامتری ندارد پس درنتیجه داخل پرانتز هیچ متغییری قرار نمیگیرد. پارامترهای توابع یک عملکرد هستند. بنابراین میتوانیم مقادیر مختلفی را به این پارامترها منتقل کنیم و نتایج مربوطه را بدست اوریم.
توجه داشته باشید که میتوانیم همان تابع را چند بار فراخوانی کنیم و نیازی به نوشتن دوبارهی کد ان برنامه را نداریم.
توابع میتوانند پارامتر بگیرند، این مقادیری است که تابع از ان استفاده میکند. حال با استفاده از این پارمترها میتوانیم روی انان عملکردی را انجام دهیم. منظور از پارامترها همان متغییرهای است که داخل پرانتز قرار میگیرند. متغییرهای که داخل پرانتز تعریف میشوند با فراخوانی تابع مقادیر از قبل تعیین شده داخل این پارمترها قرار میگیرند و تابع اجرا میشود.
پارامترهای داخل جفت پرانتز با کاما جدا میشوند. توجه داشته باشید که پارامترها همان طور که گفته شد متغییرهای داخل جفت پرانتز هستند و متغییرهای که داخل پرانتز تابعی که فراخوانی میکنید ارگومان هسنتد.
مثال (فایلی با نام function_param.py
ذخیره کنید)
برای مشاهده برنامهها بهتر است به لینک زیر سر بزنید:
{% include "./programs/function_param.py" %}
خروجی:
{% include "./programs/function_param.txt" %}
چگونه و چطوری
در اینجا ما تابع با نام print_max
تعریف میکنیم. که دارای دو پارامتر به نامهای a
و b
هستند. کار که قرار است انجام دهیم عدد بزرگتر را پیدا کنیم ان هم با استفاده از دستور if..else
و بعد عدد پیدا شده را چاپ کنیم.
با اولی که تابع print_max
را فراخوانی میکنیم، به طور مستقیم این اعداد به عنوان ارگومان به تابع معرفی میکنیم.
در گامی بعدی به تابع دو پارامتر میدهیم. که این امکان را (print_max(x, y
میدهد که مقدار ارگومان x
به a
اختصاص داده شود و ارگومان y
به b
اختصاص داده شود. تابع print_max
در هر دو مورد به یک صورت عمل میکند.
وقتی متغییری را در داخل تابعی تعریف میکنید به هیچ وجه متغییرهای هم نام خارج از تابع به هم مرتبط نیستند. این بدان معنی است در تابع متغییرهای تعریف شده محلی هستند. متغییرها در محدوده بلوک تابع قابل استفاده هستند.
برای مشاهده برنامهها بهتر است به لینک زیر سر بزنید:
برای مثال (فایلی با نام function_local.py
ذخیره کنید)
{% include "./programs/function_local.py" %}
خروجی:
{% include "./programs/function_local.txt" %}
چگونه و چطوری
اولین باری که مقدار متغییر x را در خط اول در بدنه تابع چاپ میکنیم، پایتون از مقدار اعلام شده در بلوک اصلی (در قسمت بالا تعریف تابع) استفاده میکند.
بعد مقدار 2
را به متغییر x
اختصاص میدهیم. متغییر x
یک متغییر محلی است. بنابراین هنگامی که مقدار x
در تابع تغییر میدهیم، متغییر x
تعریف شده در بلوک اصلی باقی میماند.
با استفاده از کمک دستور print
مقدار متغییر x
را که در بلوک اصلی تعریف شده است، نمایش میدهیم. پس باید درحال حاضر درکی از متغییر محلی داشته باشید.
{#global-statement}
اگر میخواهید یک متغییری در بالای برنامه خود تعریف کنید که به هیچ کلاس یا تابع محدود نباشد، پس باید به پایتون بگویید که این متغییر محلی نیست. به این نوع متغییرها متغییر سراسری میگویند. پس با استفاده از متغییر سراسری میتوانیم این کار را انجام دهیم.
فرض کنید که میخواهید که یک متغییر سراسری تعریف کنید و در خارج از تابع از ان استفاده کنید. همچنین متغییر هم نام با متغییر سراسری خود ندارید(هر چند توسعه میشود از این کار پرهیز کنید). زیرا به این خاطر سطح خوانا بودن برنامه شما را پایین میاورد.
برای مشاهده برنامهها بهتر است به لینک زیر سر بزنید:
برای مثال (فایلی با نام function_global.py
ذخیره کنید)
{% include "./programs/function_global.py" %}
خروجی:
{% include "./programs/function_global.txt" %}
چگونه و چطوری
متغییر سراسری x
را وقتی فراخوانی میکنیم، اعلام میکند که یک متغییر سراسری است. پس وقتی که متغییر x
را صدا می کنیم در بلوک اصلی این تغییرات منعکس میشود.
همچنین میتوانیم چندین متغییر سراسری تعریف کنیم، با استفاده از دستور global x, y, z
{#default-arguments}
برای بعضی از توابع ممکن است که بخواهید از پارامترهای اختیاری استفاده کنید، درصورتیکه از کاربر مقداری را تعیین نکند. این کار با استفاده از ارگومان پیشفرض انجام میشود. این روش با کمک اضافه کردن پارامترها در تعریف تابع (انتساب تابع) با علامت (=
) انجام میشود.
این نکته را در نظر داشته باشید که مقدار ارگومان باید یک مقدار ثابت باشد. این بدان معنی است که مقدار ارگومان نباید تغییر کند. در این مورد در فصلهای بعدی توضیح داده خواهد شد.
برای مشاهده برنامهها بهتر است به لینک زیر سر بزنید:
برای مثال (فایلی با نام function_default.py
ذخیره کنید)
{% include "./programs/function_default.py" %}
خروجی:
{% include "./programs/function_default.txt" %}
چگونه و چطوری
تابع با نام say
برای چاپ رشته به اندازهی که بهش گفته میشود، رشته چاپ میکند. اگر مقدار ندهیم، به طور پیشفرض یک رشته چاپ میشود. روش دادن ارگومان هم به این صورت 1
to the parameter times
است.
در سری اول از تابع say
فقط رشته را میدهیم و رشته را چاپ میکند. در روش بعدی از ارگومان 5
استفاده میکنیم به این صورت ۵ بار از رشته رونویسی میکند.
نکته
تنها پارمترهای که در انتهای لیست قرار دارند متیواند پارامتر پیشفرض بگیرند. مقدار پارامتر نمیتواند قبل از ارگومان باشد. یک مقدار ارگومان به طور پیشفرض در لیست تابع قرار دارد.
این بخاطر این دلیل است که مقادیر پارامترها بر اساس موقعیت اختصاص داده میشود. برای مثال:
(def func(a,> b=5
صحیح است،(def func(a=5, b
صحیح نیست.
اگر توابعی با پارامترهای مختلفی دارید و میخواهید بعضی از پارامترها را مشخص کنید، میتوانید با نامگذاری پارامترها این کار را انجام دهید. به این روش کلید ارگومان گفته میشود. در اینجا ما از یک کلید واژه به جای موقعیت (که قبلا از ان استفاده میکردیم) استفاده میکنیم.
دو مزیت وجود دارد: اول از همه استفاده از تابع سادهتر است، چون دیگر نیاز به نگرانی برای نظم پارامترهای تابع نداریم. دوم: میتوانیم فقط پارامترهای که میخواهیم را نامگذاری کنیم، به شرط اینکه پارامترها دیگر مقادیر پیشفرض داشته باشند.
برای مشاهده برنامهها بهتر است به لینک زیر سر بزنید:
برای مثال (فایلی با نام function_keyword.py
ذخیره کنید)
{% include "./programs/function_keyword.py" %}
خروجی:
{% include "./programs/function_keyword.txt" %}
چگونه و چطوری
تابعی به نام func
دارای یک پارامتری است که، بدون یک مقدار ارگومان پیشفرض است. همچنین پارامترهای که دارای مقدار پیشفرض هستند.
در اولین گام استفاده از (func(3,7
پارامتر a
مقدار 3
، پارامتر b
مقدار 7
و پارامتر c
مقدار پیشفرض 10
را میگیرد.
در دومین گام استفاده از (func(25, c = 24
متغییر a
به دلیل موقعیت ارگومان مقدار 25
را میگیرد. بعد پارامتر c
به دلیل کلید واژهی ارگومان مقدار 24
را میگیرد. متغییر b
هم مقدار پیشفرض 5
را به خود اختصاص میدهد.
در سومین گام استفاده از (func(c=50, a=100
از ارگومانهای کلیدی برای تمامی مقادیر مشخص شده استفاده میکنیم. این نکته را در نظر داشته باشید که اول پارامتر c
بعد این پارامتر، پارامتر a
را تعیین میکنیم. حتی اگر پارامتر a
قبل از c
در تابع تعریف شده باشد.
گاهی اوقات نیاز به این پیدا میکنید که تابعی را تعریف کنید که پارامترهای زیادی مانند مـتغیـیـر بگیرد. برای صرفهجویی در پارامترها میتوانید از این روش استفاده کنید.
برای مثال (فایلی با نام function_varargs.py
ذخیره کنید)
{% include "./programs/function_varargs.py" %}
خروجی:
{% include "./programs/function_varargs.txt" %}
چگونه و چطوری
هنگامی که پارامتری ستارهداری مانند *param
را تعریف میکنیم. سپس موقعیت ارگومان از ان نقطه به عنوان یک مرتبه به 'param' استفاده میکند.
بیان ساده تر بگم، وقتی که پارامتری با دو تا ستاره تعریف میکنیم چیزی مانند **param
پس تمامی ارگومانهای کلیدی که به تعداد کلمه از این نقطه تا اخر جمع اوری میشود با نام 'param' (یک چیزی مانند فرهنگ لغت).
در بخشهای بعدی در این مورد بیشتر بحث خواهیم کرد.
{#return-statement}
دستور return
همانطور که از نام انگلیسیاش مشخص است یک چیزی را از تابع بازمیگرداند. بعد از این عمل از تابع خارج میشویم. همچنین یک مقدار اختیاری را نیز میتوانیم از تابع برگردانیم.
برای مثال (فایلی با نام function_return.py
ذخیره کنید)
{% include "./programs/function_return.py" %}
خروجی:
{% include "./programs/function_return.txt" %}
چگونه و چطوری
تابع maximum
بزگترین پارامتر را برمیگرداند، در این قسمت ارقام به تابع فرستاده میشود. برای انجام این کار با استفاده از دستور if..else
بزرگترین مقدار را پیدا میکند. در اخر هم مقدار پیدا شده را بازمیگرداند.
نکته: دستور return
اگر بدون مقدار باشد مقدار return None
را بازمیگرداند. None
یک مقدار خاص در پایتون است که نمایشگر مقدار هیچچیز است. برای مثال برای نمایش دادن مقداری که ارزش ندارد میتوانید از مقدار None
استفاده کنید.
هر تابعی return None
مقدار هیچچیز را میگیرد مگر اینکه مقدار return
را اعلام کرده (مقدار دهی کردن) باشید.
با استفاده از دستور ((print(some_function)
میتوانید ببینید که تابع some_function
از دستور return
استفاده نمیکند.
def some_function():
pass
دستور pass
در پایتون برای نشان دادن یک بلوکخالی از فراخوانیها استفاده میشود.
نصیحت: تابعی دورنی با نام max
وجود دارد که همان عمل پیدا کردن مقدار بزگتر را انجام میدهد. پس بهتر است از این تابع برای انجام این کار استفاده کنید.
یکی از ویژگیهای عالی پایتون به نام مستندسازی رشتهها(documentation strings) است که در زبان انگلیسی به طور مخفف docstrings به این شکل میشناسیم. یک ابزار مهم است که حتما باید ان را یاد داشته باشید. اما بخاطر چی؟ این روش باعث میشود برنامهها را بهتر درک کنیم تا بتوانیم بهتر مستندسازی کنیم. البته این موضوع را هم بگم در ایران مستندسازی یک جهنمی برای برنامهنویسها است و بهتر است این فرهنگ را بیشتر ترویج دهیم(این نکته را هم عرض کنم به هیچ عنوان قصد تهمت به برنامهنویسان خوبی ایرانی ندارم). یکی از کارهای شگفت انگیزی که میتوانیم انجام دهیم این است که وقتی برنامهی در حال اجرا است میتوانیم از یک تابع مستند بسازیم.
برای مثال (فایلی با نام function_docstring.py
ذخیره کنید)
{% include "./programs/function_docstring.py" %}
خروجی:
{% include "./programs/function_docstring.txt" %}
چگونه و چطوری
در تابع در خط اول رشته موجود یک رشتهی از مستند است. توجه داشته باشید که مستندسازی رشتهی برای ماژولها و کلاسهانیز استفاده میشود. که درفصول بعدی با انها اشنا میشویم.
در ادامه مستندسازی یک چند رشتهی است که خط اول با بزرگ شروع میشود و با یک نقطه به پایان میرسد. اما خط دوم خالی است و پس از ان توضیحات دقیقی میاید که در خط سوم قرار دارد. توسعه من برای همه این است که از این روش برای توابع غیر ضروری خود مستندسازی رشتهی را استفاده کنند.
برای دسترسی به رشته-مستند با استفاده از __doc__
تابع print_max
میتوانیم این کار را انجام دهیم. این نکته را هم در نظر داشته باشید که پایتون همه چیز را به عنوان یک شی که شامل تابع است میبیند. در این مورد در فصل کلاسها بحث خواهیم کرد.
اگر از دستور ()help
پایتون استفاده میکنید روش کار با مستندسازی رشتهی را دیدهاید. کار را که انجام میدهد این است که با گرفتن ویژگی تابع __doc__
ان را به صورت شستهورفته برایمان نمایش میدهد. همچنین تابع help(print_max)
گفته شده در بالا را میتوانید در اینجا استفاده کنید. برای خارج شدن از help
هم با فشار دادن کلید q
کیبورد میتوانید خارج شوید.
همانطور که دید با استفاده از ابزارهای اماده و اتوماسیون میتوانید به راحتی مستندسازی را انجام دهید. برای همین یکی از توسعهها ضروری من این است که برای توابع غیرضروری نیز از این روش استفاده کنید. دستور pydoc
که در توزیع پایتون موجود است، مشابه دستور ()help
عمل می کند.
در این بخش جنبههای مختلف توابع را دیدیم. اما به طور کامل پوشش ندادهایم. با این حال بیشتر از انچه که از عملکرد پایتون استفاده میکنید را پوشش دادهایم.
در فصول بعدی چگونگی استفاده از ماژولها را خواهیم دید.