تابعها: به یه کار اسم بده، دوباره استفادهش کن (Functions)
تابع چند تا قدم رو زیر یه اسم بستهبندی میکنه که هر وقت خواستی اجراشون کنی. مقدارها رو بهعنوان پارامتر بهش میدی، نتیجه رو با return پس میگیری، و میبینی وقتی یه تابع یکی دیگه رو صدا میزنه روی پشتهی فراخوانی (call stack) چی میگذره.
تعریف یه تابع
def به چند تا قدم یه اسم میده
def greet(name): یه تعریف تابع رو شروع میکنه: کلمهی کلیدی def، اسم تابع، پرانتز با اسم ورودیهاش، و دونقطه. خطهای تورفتهی زیرش بدنهی تابعان. تعریف کردن یه تابع فقط این قدمها رو زیر اون اسم نگه میداره؛ هنوز هیچی اجرا نمیشه. بدنه وقتی اجرا میشه که تابع رو صدا بزنی (call)، یعنی اسمش رو با پرانتز بنویسی، مثل greet("Sara")، و هر بار که صداش بزنی دوباره اجرا میشه.
مثل یه کارت دستور پخت توی کشو: نوشتنش چیزی نمیپزه. پختن هر بار اتفاق میافته که یکی کارت رو برداره و طبقش پیش بره.
def greet(name):
print("سلام " + name)
greet("سارا")
greet("امید")سلام سارا
سلام امیدبلوک def بهتنهایی هیچی چاپ نکرد. هر کدوم از دو خط آخر greet رو صدا میزنه، و هر بار بدنه با یه اسم دیگه یه بار اجرا میشه.
خودت رو امتحان کن
تعریف کردن یه تابع با def بدنهش رو همون لحظه اجرا میکنه.
جواب رو ببین
نادرست
غلطه. def فقط قدمها رو زیر یه اسم نگه میداره. بدنه وقتی اجرا میشه که تابع رو صدا بزنی، مثلاً greet("Sara")، و با هر بار صدا زدن دوباره اجرا میشه.
پارامتر و آرگومان (Parameter and Argument)
پارامتر اسمیه که توی پرانتزِ تعریف تابع میاد: توی def area(w, h):، w و h پارامترن. آرگومان مقداریه که موقع صدا زدن بهش میدی: توی area(3, 4)، 3 و 4 آرگومانن. هر بار که تابع صدا زده میشه، آرگومانها به ترتیب به پارامترها میرسن، پس w میشه 3 و h میشه 4.
اینجا area(3, 4) و area(4, 3) یه مساحت میدن، ولی برای تابعی مثل minus(a, b)، جابهجا کردن آرگومانها جواب رو عوض میکنه.
def area(w, h):
return w * h
result = area(3, 4)
print(result)
print(area(2, 5) + 1)12
11return مقدار رو برمیگردونه به همون جایی که تابع رو صدا زده. area(3, 4) میشه 12 و توی result نگه داشته میشه؛ area(2, 5) میشه 10، و + 1 بعد از برگشتنش حساب میشه.
خودت رو امتحان کن
def double(n):
return n * 2
print(double(4) + 1)91085
جواب رو ببین
9درسته. double(4) عدد 8 رو برمیگردونه، و بعد 8 + 1 میشه 9.
قدمبهقدم ببین

main میرسه به result = area(3, 4) قاب (frame) خود برنامه، یعنی main، پایین پشته نشسته، با خط result = area(3, 4) و یه جعبهی خالی برای result. تعریف area بالا سمت راست گوشهای وایستاده. main باید همینجا صبر کنه تا area یه جواب پس بفرسته.

صدا زدن یه قاب area روی پشته میذاره: w = 3، h = 4 صدا زدن area یه قاب تازه به اسم area بالای main میذاره. فلشها آرگومانهای 3 و 4 رو از خط صدا زدن، به ترتیب، میبرن توی جعبههاش، پس پارامترها میشن w = 3 و h = 4. این جعبهها مال همین یه بار صدا زدنن.

w * h میشه 12، و return 12 برمیگرده داخل قاب area، حاصل w * h میشه 12. فلش return 12 از قاب بیرون میاد و پایین میره سمت جعبهی خالی result توی main: return مقدار رو به همونی برمیگردونه که صداش زده بود.

قاب area رفته؛ result شده 12 قاب area از روی پشته محو شده و w و h هم باهاش رفتن: اینها محلیِ (local) همون یه بار صدا زدن بودن. فقط main مونده، و حالا جعبهی resultـش 12 رو نگه داشته، پس برنامه از خط بعد از صدا زدن ادامه میده.
خودت رو امتحان کن
هر کلمه رو به معنیش وصل کن
جواب رو ببین
- def → تعریف یه تابع رو شروع میکنه
- پارامتر → یه اسم توی پرانتزِ تعریف، مثل w
- آرگومان → یه مقدار که موقع صدا زدن داده میشه، مثل 3
- return → یه مقدار رو به صدازننده برمیگردونه و تابع رو تموم میکنه
print نشون میده، return پس میده
print داخل تابع
مقدار رو روی صفحه میذاره که یه آدم بخونه. خود برنامه هیچی پس نمیگیره، پس نمیتونی نگهش داری، چیزی بهش اضافه کنی یا جای دیگه بفرستیش.
return داخل تابع
مقدار رو به خطی که تابع رو صدا زده پس میده، جایی که میشه نگهش داشت (result = area(3, 4))، توی حساب ازش استفاده کرد یا چاپش کرد.
تابعی که return نداره None برمیگردونه، یعنی مقدار پایتون برای «هیچی».
def greet(name):
print("Hi " + name)
x = greet("Sara")
print(x)Hi Sara
Noneخط اول خروجی از print داخل greet میاد. greet هیچ returnی نداره، پس x مقدار None رو میگیره و print(x) همون رو نشون میده. این رایجترین قاطیکاری مبتدیها با تابعهاست.
خودت رو امتحان کن
def area(w, h):print(w * h)x = area(3, 4)print(x + 1)
جواب رو ببین
اشکال توی خط ۲.
درسته. area عدد 12 رو چاپ میکنه ولی هیچی برنمیگردونه، پس x میشه None و x + 1 با TypeError میخوابه. print(w * h) رو بکن return w * h.
متغیرهای محلی
هر چی توی تابع اتفاق میافته، توی تابع میمونه
پارامترها و هر متغیری که داخل یه تابع میسازی محلی (local)ان: فقط تا وقتی اون بار صدا زدن در حال اجراست وجود دارن، توی قاب خودش روی پشته. وقتی تابع برمیگرده، قاب برداشته میشه و اونها هم از بین میرن. پس بعد از area(3, 4)، نوشتن print(w) بیرون تابع یه NameErrorـه: w هیچوقت یه اسم توی main نبوده. اگه یه مقدار رو بیرون لازم داری، returnـش کن.
دو بار صدا زدن، area(3, 4) و area(2, 5)، هر کدوم w و h خودشون رو دارن. هیچوقت مال همدیگه رو نمیبینن یا روش نمینویسن.
اصلاً چرا تابع
- یه بار بنویس، چند بار استفاده کن. minutes(3) و minutes(5) هر دو از همون def minutes(hours): return hours * 60 استفاده میکنن.
- یه جا برای درست کردن. اگه فرمول اشتباه بود، توی def درستش میکنی و همهی صدا زدنها درست میشن.
- یه اسم خوب کد رو توضیح میده. to_toman(50000) میگه چیکار میکنه (تبدیل ریال به تومن)؛ 50000 // 10 مجبورت میکنه حدس بزنی.
- مقدار پیشفرض یه امکان اضافهست. def greet(name="friend"): اجازه میده greet() رو بدون آرگومان صدا بزنی.
خودت رو امتحان کن
رضا def area(w, h): return w * h رو تعریف میکنه، result = area(3, 4) رو اجرا میکنه و بعد، بیرون تابع، مینویسه print(w). چی میشه؟
- 3 رو چاپ میکنه، آخرین مقداری که w داشت
- 12 رو چاپ میکنه
- NameError، چون w فقط داخل همون بار صدا زدن وجود داشت
- None رو چاپ میکنه
جواب رو ببین
NameError، چون w فقط داخل همون بار صدا زدن وجود داشت
درسته. w یه متغیر محلی توی قاب area بود. وقتی area برگشت اون قاب برداشته شد، پس توی main اسمی به اسم w وجود نداره.
مرور درس
- def name(params): قدمها رو زیر یه اسم نگه میداره؛ بدنه فقط وقتی اجرا میشه که name(args) رو صدا بزنی.
- پارامترها اسمهای توی تعریفن؛ آرگومانها مقدارهاییان که میدی، و به ترتیب جفت میشن.
- return یه مقدار رو به صدازننده پس میده؛ تابعی که return نداره None برمیگردونه.
- print یه مقدار رو به آدم نشون میده؛ return اون رو به برنامه میده که نگهش داره یا ازش استفاده کنه.
- هر بار صدا زدن یه قاب مخصوص خودش روی پشتهی فراخوانی میگیره، با متغیرهای محلی که وقتی برمیگرده از بین میرن.