توابع در پایتون؛ تعریف تابع با def و استفاده از return

🗓 آخرین بهروزرسانی:
تابع یکی از مهمترین ابزارهای پایتون برای سازماندهی کد، جلوگیری از تکرار و ساخت برنامههای قابل نگهداری است. با تعریف یک تابع میتوان مجموعهای از دستورها را یک بار نوشت و هر زمان لازم بود آن را با دادههای مختلف اجرا کرد.
این مطلب، درس چهارم از دوره رایگان پایتون سطح متوسط است. در درس قبلی با مجموعهها و عملیات Set آشنا شدیم. اکنون یاد میگیریم چگونه منطق برنامه را داخل توابع مستقل قرار دهیم و نتیجه محاسبات را با return برگردانیم.
تابع در پایتون چیست؟
تابع یا function یک بخش نامگذاریشده از کد است که وظیفه مشخصی را انجام میدهد. برای نمونه، میتوان تابعی ساخت که پیام خوشآمدگویی نمایش دهد، میانگین نمرات را محاسبه کند یا اعتبار یک رمز عبور را بررسی کند.
مزیتهای اصلی استفاده از تابع:
- کاهش تکرار کد
- تقسیم برنامه به بخشهای کوچک و قابل فهم
- آزمایش و رفع خطای سادهتر
- استفاده دوباره از منطق برنامه
- افزایش خوانایی و نگهداریپذیری کد
تعریف تابع با def
برای ساخت تابع از کلمه کلیدی def استفاده میکنیم:
def show_message():
print("به دوره پایتون خوش آمدید")در این ساختار:
defآغاز تعریف تابع است.show_messageنام تابع است.- پرانتزها محل تعریف پارامترها هستند.
- علامت دونقطه
:پایان سرآیند تابع را مشخص میکند. - دستورهای تورفته بدنه تابع را تشکیل میدهند.
فراخوانی تابع
تعریف تابع بهتنهایی باعث اجرای آن نمیشود. برای اجرا باید نام تابع را همراه با پرانتز بنویسیم:
def show_message():
print("به دوره پایتون خوش آمدید")
show_message()خروجی:
به دوره پایتون خوش آمدیدمیتوان تابع را چند بار فراخوانی کرد:
show_message()
show_message()
show_message()ترتیب تعریف و فراخوانی تابع
پایتون باید پیش از فراخوانی، تعریف تابع را اجرا کرده باشد. کد زیر درست است:
def greet():
print("سلام")
greet()اما اگر فراخوانی پیش از تعریف قرار گیرد، معمولاً خطای NameError ایجاد میشود:
greet()
def greet():
print("سلام")قواعد نامگذاری توابع
نام تابع باید واضح و نشاندهنده وظیفه آن باشد. براساس سبک رایج پایتون، نام توابع با حروف کوچک و زیرخط نوشته میشود:
def calculate_total():
pass
def validate_email():
pass
def show_user_profile():
passنکات مهم:
- نام تابع نباید با عدد آغاز شود.
- فاصله و خط تیره در نام تابع مجاز نیست.
- از کلمات رزروشده مانند
if،forیاclassاستفاده نکنید. - نامهایی مانند
xیاdo_itمعمولاً معنای کافی ندارند. - از نام توابع داخلی مانند
list،sumیاprintبرای متغیر و تابع خودداری کنید.
تابع بدون ورودی
سادهترین تابع هیچ دادهای دریافت نمیکند:
def show_menu():
print("1. افزودن محصول")
print("2. نمایش محصولات")
print("3. خروج")
show_menu()این تابع هر بار همان منو را نمایش میدهد.
پارامتر و آرگومان چیست؟
تابع میتواند اطلاعاتی از بیرون دریافت کند. نامی که هنگام تعریف تابع داخل پرانتز قرار میگیرد پارامتر و مقداری که هنگام فراخوانی ارسال میشود آرگومان نام دارد:
def greet(name):
print(f"سلام {name}")
greet("مهران")در این مثال:
nameپارامتر تابع است."مهران"آرگومان ارسالشده به تابع است.
جزئیات انواع پارامتر و آرگومان را در درس بعدی کامل بررسی میکنیم.
تابع با چند پارامتر
def introduce(name, city):
print(f"من {name} هستم و در {city} زندگی میکنم.")
introduce("مهران", "استانبول")تعداد آرگومانها باید با پارامترهای موردنیاز هماهنگ باشد؛ در غیر این صورت خطای TypeError ایجاد میشود.
مقدار پیشفرض برای پارامتر
میتوان برای پارامتر مقدار پیشفرض تعیین کرد:
def greet(name, message="سلام"):
print(f"{message} {name}")
greet("سارا")
greet("علی", "خوش آمدی")در فراخوانی نخست، مقدار پیشفرض message استفاده میشود. در فراخوانی دوم، آرگومان جدید جایگزین مقدار پیشفرض میشود.
ترتیب پارامترهای پیشفرض
پارامتر بدون مقدار پیشفرض باید پیش از پارامترهای پیشفرض قرار گیرد:
def create_user(name, active=True):
print(name, active)نسخه زیر از نظر نحوی نادرست است:
def create_user(active=True, name):
passدستور return در پایتون
دستور return نتیجه تابع را به محل فراخوانی برمیگرداند:
def add(number1, number2):
result = number1 + number2
return result
total = add(10, 20)
print(total)خروجی:
30مقدار برگشتی را میتوان در متغیر ذخیره کرد، در محاسبه دیگری استفاده کرد یا مستقیماً به تابع دیگری فرستاد.
تفاوت print و return
print() فقط یک مقدار را روی صفحه نمایش میدهد؛ اما return مقدار را از تابع خارج میکند تا بخشهای دیگر برنامه بتوانند از آن استفاده کنند.
def add_with_print(a, b):
print(a + b)
result = add_with_print(5, 3)
print("مقدار result:", result)خروجی:
8
مقدار result: Noneتابع مقدار ۸ را نمایش داده، اما آن را برنگردانده است؛ بنابراین مقدار متغیر result برابر None میشود.
نسخه مناسب برای استفاده مجدد:
def add(a, b):
return a + b
result = add(5, 3)
print(result * 2)تابع بدون return چه مقداری برمیگرداند؟
هر تابع پایتون یک مقدار برمیگرداند. اگر return نوشته نشود، مقدار برگشتی بهصورت خودکار None است:
def show_text():
print("Python")
value = show_text()
print(value)پایان اجرای تابع با return
بهمحض اجرای return، تابع پایان مییابد و دستورهای بعد از آن اجرا نمیشوند:
def check_number(number):
if number > 0:
return "مثبت"
return "صفر یا منفی"
print(check_number(10))وقتی شرط درست باشد، نخستین return اجرا و تابع فوراً متوقف میشود.
بازگشت زودهنگام یا Early Return
بازگشت زودهنگام به سادهترشدن شرطها کمک میکند:
def calculate_discount(price, percent):
if price < 0:
return "قیمت نامعتبر است"
if percent < 0 or percent > 100:
return "درصد تخفیف نامعتبر است"
discount = price * percent / 100
return price - discountورودیهای نامعتبر در ابتدای تابع بررسی میشوند و منطق اصلی با تورفتگی کمتر نوشته میشود.
بازگرداندن عبارت مستقیم
لازم نیست نتیجه ابتدا در متغیر ذخیره شود:
def multiply(a, b):
return a * b
print(multiply(4, 6))استفاده از مقدار برگشتی در محاسبات
def calculate_tax(price):
return price * 0.10
product_price = 500000
tax = calculate_tax(product_price)
final_price = product_price + tax
print(final_price)فراخوانی یک تابع داخل تابع دیگر
def calculate_discount(price, percent):
return price * percent / 100
def calculate_final_price(price, percent):
discount = calculate_discount(price, percent)
return price - discount
print(calculate_final_price(1000, 20))این روش هر تابع را مسئول یک کار مشخص نگه میدارد.
در پایتون حتی میتوان یک تابع را به تابع دیگر داد و تابع تازهای تحویل گرفت؛ این ایده پایهی دکوراتور در پایتون است که بعد از تسلط بر توابع، قدم بعدی خوبی برای یادگیری است. همچنین در آموزش تابع بازگشتی در پایتون میبینید که یک تابع چطور میتواند برای حل مسئله، خودش را دوباره صدا بزند.
بازگرداندن چند مقدار از تابع
تابع میتواند چند مقدار را با ویرگول برگرداند. پایتون این مقدارها را داخل یک تاپل قرار میدهد:
def calculate_stats(numbers):
minimum = min(numbers)
maximum = max(numbers)
average = sum(numbers) / len(numbers)
return minimum, maximum, average
result = calculate_stats([10, 15, 20])
print(result)خروجی:
(10, 20, 15.0)میتوان نتیجه را مستقیماً باز کرد:
minimum, maximum, average = calculate_stats([10, 15, 20])
print(minimum)
print(maximum)
print(average)بازگرداندن دیکشنری از تابع
وقتی نتیجه شامل چند داده نامگذاریشده است، دیکشنری خوانایی بیشتری دارد:
def create_product_report(name, price, stock):
return {
"name": name,
"price": price,
"stock": stock,
"available": stock > 0
}
report = create_product_report("کتاب پایتون", 250000, 8)
print(report["available"])تابع و شرطها
def get_grade(score):
if score >= 90:
return "عالی"
elif score >= 75:
return "خوب"
elif score >= 50:
return "قبول"
else:
return "مردود"
print(get_grade(82))تابع و حلقهها
def count_even_numbers(numbers):
count = 0
for number in numbers:
if number % 2 == 0:
count += 1
return count
print(count_even_numbers([1, 2, 4, 7, 10]))تابع و ساختارهای داده
توابع میتوانند لیست، تاپل، دیکشنری و Set دریافت یا برگردانند:
def remove_duplicates(items):
return list(dict.fromkeys(items))
names = ["علی", "سارا", "علی", "رضا"]
print(remove_duplicates(names))متغیرهای محلی در تابع
متغیری که داخل تابع ساخته میشود معمولاً فقط در همان تابع قابل دسترسی است:
def calculate_total():
total = 100 + 200
return total
print(calculate_total())دسترسی مستقیم به total بیرون تابع خطای NameError ایجاد میکند. مفهوم کامل محدوده متغیرهای محلی و سراسری در یکی از درسهای آینده بررسی خواهد شد.
مستندسازی تابع با Docstring
یک رشته در نخستین خط بدنه تابع میتواند هدف، ورودی و خروجی آن را توضیح دهد:
def calculate_area(width, height):
"""مساحت مستطیل را براساس عرض و ارتفاع برمیگرداند."""
return width * height
print(calculate_area.__doc__)Docstring برای پروژههای تیمی، ابزارهای توسعه و مستندات خودکار بسیار مفید است.
Type Hint در تعریف تابع
میتوان نوع مورد انتظار پارامترها و مقدار برگشتی را بهصورت راهنما مشخص کرد:
def calculate_area(width: float, height: float) -> float:
return width * heightType Hint به خوانایی و ابزارهای بررسی کد کمک میکند، اما بهتنهایی مانع ارسال نوع داده اشتباه نمیشود.
دستور pass در تابع
اگر ساختار تابع را نوشتهایم اما هنوز بدنه آن آماده نیست، میتوانیم موقتاً از pass استفاده کنیم:
def send_email():
passpass هیچ عملی انجام نمیدهد، اما از ایجاد خطای نحوی جلوگیری میکند.
اشتباه رایج: فراموشکردن پرانتز فراخوانی
def greet():
return "سلام"
print(greet)
print(greet())عبارت greet خود تابع را نشان میدهد، اما greet() تابع را اجرا میکند و مقدار برگشتی را میدهد.
اشتباه رایج: استفاده از نتیجه print
def calculate(a, b):
print(a + b)
result = calculate(4, 5)
print(result)برای استفاده از نتیجه در بخش دیگری از برنامه باید بهجای print از return استفاده شود.
اشتباه رایج: کد پس از return
def example():
return 10
print("این خط اجرا نمیشود")کدی که پس از return و در همان مسیر اجرا قرار دارد، دستنیافتنی است.
اشتباه رایج: تغییر ورودی قابلتغییر
اگر لیست یا دیکشنری به تابع ارسال شود، تغییر مستقیم آن میتواند روی داده اصلی اثر بگذارد:
def add_item(items):
items.append("جدید")
products = ["کتاب", "دفتر"]
add_item(products)
print(products)برای جلوگیری از تغییر داده اصلی میتوان یک کپی ساخت:
def add_item_safely(items):
new_items = items.copy()
new_items.append("جدید")
return new_itemsاشتباه رایج: مقدار پیشفرض قابلتغییر
استفاده از لیست خالی بهعنوان مقدار پیشفرض میتواند نتیجه غیرمنتظره ایجاد کند:
def add_task(task, tasks=[]):
tasks.append(task)
return tasksروش امنتر:
def add_task(task, tasks=None):
if tasks is None:
tasks = []
tasks.append(task)
return tasksپروژه اول: ماشینحساب تابعمحور
در این پروژه، هر عملیات در یک تابع مستقل قرار میگیرد:
def add(a, b):
return a + b
def subtract(a, b):
return a - b
def multiply(a, b):
return a * b
def divide(a, b):
if b == 0:
return None
return a / b
def calculate(a, operator, b):
if operator == "+":
return add(a, b)
elif operator == "-":
return subtract(a, b)
elif operator == "*":
return multiply(a, b)
elif operator == "/":
return divide(a, b)
return None
first_number = float(input("عدد اول: "))
operator = input("عملگر (+ - * /): ").strip()
second_number = float(input("عدد دوم: "))
result = calculate(first_number, operator, second_number)
if result is None:
print("محاسبه انجام نشد؛ عملگر نامعتبر است یا تقسیم بر صفر رخ داده است.")
else:
print("نتیجه:", result)پروژه دوم: گزارش نمرات با توابع
def calculate_average(scores):
if len(scores) == 0:
return 0
return sum(scores) / len(scores)
def get_status(average):
if average >= 17:
return "عالی"
elif average >= 12:
return "قبول"
return "نیازمند تلاش بیشتر"
def create_report(name, scores):
average = calculate_average(scores)
return {
"name": name,
"average": average,
"status": get_status(average),
"highest": max(scores) if scores else None,
"lowest": min(scores) if scores else None
}
report = create_report("سارا", [18, 15, 20, 17])
for key, value in report.items():
print(key, ":", value)تمرینهای پیشنهادی
- تابعی بنویسید که یک نام دریافت کند و پیام خوشآمدگویی برگرداند.
- تابعی بسازید که طول و عرض را دریافت و مساحت و محیط مستطیل را برگرداند.
- تابعی بنویسید که یک عدد دریافت کند و زوج یا فرد بودن آن را برگرداند.
- تابعی بسازید که لیستی از عددها را دریافت و مجموع، میانگین، کمترین و بیشترین مقدار را برگرداند.
- تابعی بنویسید که قیمت و درصد تخفیف را دریافت و قیمت نهایی را محاسبه کند.
- تابعی بسازید که متن را دریافت و تعداد واژههای آن را برگرداند.
- تابعی بنویسید که رمز عبور را براساس حداقل طول و وجود عدد بررسی کند.
- تابعی بسازید که لیست نامها را دریافت و نسخه بدون تکرار آن را با حفظ ترتیب برگرداند.
- برنامه ماشینحساب را طوری توسعه دهید که توان و باقیمانده را نیز پشتیبانی کند.
- پروژه گزارش نمرات را طوری تغییر دهید که وضعیت هر نمره را نیز در یک لیست برگرداند.
📌 همچنین بخوانید: بازار کار پایتون در ایران، دستورهای break، continue و pass در پایتون و ساخت ربات تلگرام با پایتون
پرسشهای متداول
آیا تعریف تابع باعث اجرای آن میشود؟
خیر. پس از تعریف باید تابع را با نوشتن نام و پرانتز فراخوانی کنید.
تفاوت پارامتر و آرگومان چیست؟
پارامتر نامی است که در تعریف تابع نوشته میشود؛ آرگومان مقداری است که هنگام فراخوانی به تابع ارسال میشود.
تفاوت print و return چیست؟
print فقط مقدار را نمایش میدهد؛ return مقدار را برای استفاده در بخشهای دیگر برنامه از تابع خارج میکند.
آیا یک تابع میتواند چند مقدار برگرداند؟
بله. مقدارها با ویرگول برگردانده میشوند و پایتون آنها را داخل یک تاپل قرار میدهد.
چرا خروجی تابع من None است؟
احتمالاً تابع return ندارد، یا مسیر اجرای فعلی به دستور return نرسیده است.
آیا میتوان داخل یک تابع، تابع دیگری را فراخوانی کرد؟
بله. این روش برای تقسیم منطق برنامه به وظایف کوچک و مستقل بسیار رایج است.
جمعبندی
در این درس یاد گرفتیم چگونه با def تابع تعریف کنیم، آن را فراخوانی کنیم، داده دریافت کنیم و با return نتیجه را برگردانیم. همچنین تفاوت print و return، بازگشت زودهنگام، بازگرداندن چند مقدار، Docstring، Type Hint و خطاهای رایج را بررسی کردیم.
درس بعدی: پارامتر و آرگومان در توابع پایتون؛ آرگومان موقعیتی، کلیدواژهای و مقدار پیشفرض.
برای ذخیره پیشرفت در همه دستگاهها و دریافت گواهی پایان مسیر، رایگان ثبتنام کن یا وارد شو.