توابع در پایتون


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

کاربرد های تابع در پایتون

توابع در پایتون یکی از ابزارهای اساسی و کلیدی هستند که برای سازماندهی و مدیریت کدها مورد استفاده قرار می‌گیرند. در ادامه به چند کاربرد اصلی توابع در پایتون اشاره می‌کنم:

1. کاهش تکرار کد:

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

2. سازماندهی کد:

   - توابع کمک می‌کنند تا کد به بخش‌های منطقی تقسیم شود. این کار موجب می‌شود که کدها خواناتر و قابل فهم‌تر باشند.

3. استفاده مجدد:

   - توابع می‌توانند بارها در برنامه فراخوانی شوند. این ویژگی به برنامه‌نویس این امکان را می‌دهد که از توابع نوشته شده در پروژه‌های مختلف دوباره استفاده کند.

4. قابلیت نگهداری:

   - با تقسیم کردن کد به توابع، تغییرات در یک بخش از کد به سادگی انجام می‌شود بدون اینکه به سایر بخش‌ها آسیبی برسد. این امر نگهداری و به‌روزرسانی کد را ساده‌تر می‌کند.

5. ایجاد کد قابل تست:

   - توابع می‌توانند به سادگی تست شوند، که این امر به برنامه‌نویس کمک می‌کند تا اشکالات را راحت‌تر پیدا کند و به رفع آنها بپردازد.

6. پنهان‌سازی جزئیات:

   - توابع می‌توانند جزئیات پیچیده را پنهان کنند و فقط یک رابط ساده برای استفاده در اختیار قرار دهند. این ویژگی موجب می‌شود که کار با توابع آسان‌تر شود.

7. تعامل با ورودی‌ها و خروجی‌ها:

   - توابع می‌توانند ورودی‌های مختلفی بپذیرند و خروجی‌های مختلفی تولید کنند. این امر باعث افزایش انعطاف‌پذیری و کارایی برنامه می‌شود.

 

به طور کلی، توابع ابزاری قدرتمند برای نوشتن کدهای تمیز، قابل فهم و قابل نگهداری در پایتون هستند.

 

۱. تعریف یک تابع

برای تعریف یک تابع در پایتون، از کلمه کلیدی `def` استفاده می‌کنیم. ساختار کلی تعریف یک تابع به شکل زیر است:

def نام_تابع(آرگومان‌ها):
    # بدنه تابع
    # کدهایی که باید اجرا شوند
    return مقدار

مثال:

def greet():
    print("سلام! خوش آمدید!")

این تابع وقتی که فراخوانی شود، پیام خوشامدگویی را چاپ می‌کند.

۲. فراخوانی یک تابع

برای استفاده از تابع، کافی است نام آن را همراه با پرانتز بنویسیم:

greet()  # خروجی: سلام! خوش آمدید!

۳. توابع با آرگومان

توابع می‌توانند ورودی‌هایی به نام آرگومان دریافت کنند. این ورودی‌ها می‌توانند در بدنه تابع استفاده شوند.

مثال:

def add(a, b):
    return a + b

result = add(3, 5)
print(result)  # خروجی: 8

۴. توابع با آرگومان‌های پیش‌فرض

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

مثال:

def greet(name="دوست"):
    print(f"سلام، {name}!")

greet()          # خروجی: سلام، دوست!
greet("علی")    # خروجی: سلام، علی!

۵. توابع با تعداد متغیر آرگومان

اگر نمی‌دانید چه تعداد آرگومان به تابع ارسال می‌شود، می‌توانید از *args و **kwargs استفاده کنید.

- *args برای دریافت آرگومان‌های نامشخص به شکل یک لیست.

- **kwargs برای دریافت آرگومان‌های کلید-مقدار به شکل یک دیکشنری.

مثال:

def print_numbers(*args):
    for number in args:
        print(number)

print_numbers(1, 2, 3, 4)  # خروجی: 1 2 3 4

6. توابع لامبدا

توابع لامبدا، توابع بدون نام (anonymous functions) هستند که می‌توانند در یک خط تعریف شوند. این توابع معمولاً برای عملیات‌های ساده استفاده می‌شوند.

مثال:

square = lambda x: x * x
print(square(4))  # خروجی: 16

7. Passing a List as an Argument

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

مثال:

def print_list(my_list):
    for item in my_list:
        print(item)

numbers = [1, 2, 3, 4, 5]
print_list(numbers)

خروجی:

1
2
3
4
5

8. Return Values

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

مثال:

def multiply(a, b):
    return a * b

result = multiply(3, 4)
print(result)  # خروجی: 12

9. The pass Statement

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

مثال:

def placeholder_function():
    pass  # در حال حاضر هیچ عملیاتی انجام نمی‌شود

print("این تابع به زودی تکمیل خواهد شد.")

10. Positional-Only Arguments

آرگومان‌های تنها موقعیتی (Positional-Only) آرگومان‌هایی هستند که فقط باید به صورت موقعیتی (بدون کلید) به تابع ارسال شوند. این نوع آرگومان‌ها با استفاده از / در تعریف تابع مشخص می‌شوند.

مثال:

def my_function(a, b, /):
    return a + b

result = my_function(2, 3)  # خروجی: 5
# result = my_function(a=2, b=3)  # این خط خطا می‌دهد

10. Keyword-Only Arguments

آرگومان‌های فقط کلیدی (Keyword-Only) آرگومان‌هایی هستند که باید به صورت کلید-مقدار به تابع ارسال شوند. این نوع آرگومان‌ها با استفاده از * در تعریف تابع مشخص می‌شوند.

مثال:

def my_function(a, b, *, c):
    return a + b + c

result = my_function(1, 2, c=3)  # خروجی: 6
# result = my_function(1, 2, 3)  # این خط خطا می‌دهد

11. Combine Positional-Only and Keyword-Only

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

مثال:

def my_function(a, b, /, c, *, d):
    return a + b + c + d

result = my_function(1, 2, 3, d=4)  # خروجی: 10
# result = my_function(1, 2, c=3, d=4)  # این خط خطا می‌دهد

12. توابع بازگشتی (Recursion)

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

مفهوم بازگشت

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

مثال ساده

فرض کنید می‌خواهیم فاکتوریل یک عدد را محاسبه کنیم. فاکتوریل یک عدد (مثلاً ۵) برابر است با حاصل‌ضرب همه اعداد مثبت تا آن عدد:

- فاکتوریل ۵ (5!) = 5 × 4 × 3 × 2 × 1 = 120

ما می‌توانیم این کار را با استفاده از یک تابع بازگشتی انجام دهیم.

کد تابع فاکتوریل:

def factorial(n):
    if n == 1:  # اگر n برابر 1 باشد
        return 1  # فاکتوریل 1 برابر 1 است
    else:
        return n * factorial(n - 1)  # در غیر این صورت، n را در فاکتوریل (n-1) ضرب می‌کنیم

چگونه این تابع کار می‌کند:

1. اگر عددی که به تابع می‌دهیم (مثلاً ۵) برابر ۱ باشد، تابع ۱ را برمی‌گرداند.

2. اگر عدد بزرگ‌تر از ۱ باشد، تابع خودش را با عددی که یک واحد کمتر است (مثلاً ۴) صدا می‌زند و حاصل‌ضرب آن را در عدد اصلی قرار می‌دهد.

مراحل محاسبه فاکتوریل ۵:

- `factorial(5)` → ۵ × `factorial(4)`

- `factorial(4)` → ۴ × `factorial(3)`

- `factorial(3)` → ۳ × `factorial(2)`

- `factorial(2)` → ۲ × `factorial(1)`

- `factorial(1)` → ۱

حالا که factorial(1) به ۱ رسیده، دیگر نیازی به صدا زدن تابع نیست و می‌توانیم جواب‌ها را به عقب برگردانیم:

- `factorial(2)` = ۲ × ۱ = ۲

- `factorial(3)` = ۳ × ۲ = ۶

- `factorial(4)` = ۴ × ۶ = ۲۴

- `factorial(5)` = ۵ × ۲۴ = ۱۲۰

 

مثال دنباله فیبوناچی

در دنباله فیبوناچی، هر عدد برابر با مجموع دو عدد قبلی خود است. دنباله فیبوناچی به این شکل است:

- ۰، ۱، ۱، ۲، ۳، ۵، ۸، ۱۳، ۲۱، ۳۴ و ...

فرمول دنباله فیبوناچی به این شکل است:

- \( F(0) = 0 \)

- \( F(1) = 1 \)

- \( F(n) = F(n-1) + F(n-2) \) برای \( n > 1 \)

مثال تابع بازگشتی برای فیبوناچی

حالا بیایید تابعی برای محاسبه عدد \( n \)ام دنباله فیبوناچی بنویسیم:

def fibonacci(n):
    if n == 0:  # اگر n برابر 0 باشد
        return 0  # عدد فیبوناچی 0 برابر 0 است
    elif n == 1:  # اگر n برابر 1 باشد
        return 1  # عدد فیبوناچی 1 برابر 1 است
    else:
        return fibonacci(n - 1) + fibonacci(n - 2)  # در غیر این صورت، F(n) برابر با F(n-1) + F(n-2) است

چگونه این تابع کار می‌کند:

1. اگر \( n \) برابر ۰ باشد، تابع ۰ را برمی‌گرداند.

2. اگر \( n \) برابر ۱ باشد، تابع ۱ را برمی‌گرداند.

3. اگر \( n \) بزرگ‌تر از ۱ باشد، تابع خودش را با \( n-1 \) و \( n-2 \) صدا می‌زند و حاصل‌جمع آن‌ها را برمی‌گرداند.

مراحل محاسبه \( F(5) \):

- `fibonacci(5)` → `fibonacci(4)` + `fibonacci(3)`

- `fibonacci(4)` → `fibonacci(3)` + `fibonacci(2)`

- `fibonacci(3)` → `fibonacci(2)` + `fibonacci(1)`

- `fibonacci(2)` → `fibonacci(1)` + `fibonacci(0)`

- `fibonacci(1)` → ۱

- `fibonacci(0)` → ۰

حالا که به \( F(0) \) و \( F(1) \) رسیدیم، می‌توانیم به عقب برگردیم:

- `fibonacci(2)` = ۱ + ۰ = ۱

- `fibonacci(3)` = ۱ + ۱ = ۲

- `fibonacci(4)` = ۲ + ۱ = ۳

- `fibonacci(5)` = ۳ + ۲ = ۵

بنابراین، عدد پنجم دنباله فیبوناچی برابر ۵ است.

 

مثال محاسبه مجموع اعداد از ۱ تا \( n \)

فرض کنید می‌خواهیم مجموع اعداد از ۱ تا یک عدد خاص \( n \) را محاسبه کنیم. به عنوان مثال، اگر \( n = 5 \)، مجموع \( 1 + 2 + 3 + 4 + 5 = 15 \) خواهد بود.

حالا می‌توانیم یک تابع بازگشتی برای محاسبه این مجموع بنویسیم:

def sum_recursive(n):
    if n == 1:  # اگر n برابر 1 باشد
        return 1  # مجموع 1 برابر 1 است
    else:
        return n + sum_recursive(n - 1)  # در غیر این صورت، مجموع n برابر n + مجموع اعداد از 1 تا n-1 است

چگونه این تابع کار می‌کند:

1. اگر \( n \) برابر ۱ باشد، تابع ۱ را برمی‌گرداند.

2. اگر \( n \) بزرگ‌تر از ۱ باشد، تابع خودش را با \( n-1 \) صدا می‌زند و \( n \) را به آن اضافه می‌کند.

مراحل محاسبه مجموع اعداد از ۱ تا ۵:

- `sum_recursive(5)` → ۵ + `sum_recursive(4)`

- `sum_recursive(4)` → ۴ + `sum_recursive(3)`

- `sum_recursive(3)` → ۳ + `sum_recursive(2)`

- `sum_recursive(2)` → ۲ + `sum_recursive(1)`

- `sum_recursive(1)` → ۱

حالا که به \( n = 1 \) رسیدیم، می‌توانیم به عقب برگردیم:

- `sum_recursive(2)` = ۲ + ۱ = ۳

- `sum_recursive(3)` = ۳ + ۳ = ۶

- `sum_recursive(4)` = ۴ + ۶ = ۱۰

- `sum_recursive(5)` = ۵ + ۱۰ = ۱۵

بنابراین، مجموع اعداد از ۱ تا ۵ برابر ۱۵ است.

 

مثال محاسبه توان یک عدد

فرض کنید می‌خواهیم یک عدد را به یک توان خاص برسانیم. به عنوان مثال، اگر \( a = 2 \) و \( n = 3 \)، آنگاه \( 2^3 = 2 \times 2 \times 2 = 8 \) خواهد بود.

مثال تابع بازگشتی برای محاسبه توان

حالا می‌توانیم یک تابع بازگشتی برای محاسبه این قدرت بنویسیم:

def power_recursive(a, n):
    if n == 0:  # اگر n برابر 0 باشد
        return 1  # هر عددی به توان 0 برابر 1 است
    else:
        return a * power_recursive(a, n - 1)  # در غیر این صورت، a را در a به توان (n-1) ضرب می‌کنیم

چگونه این تابع کار می‌کند:

1. اگر \( n \) برابر ۰ باشد، تابع ۱ را برمی‌گرداند (چون هر عددی به توان صفر برابر ۱ است).

2. اگر \( n \) بزرگ‌تر از ۰ باشد، تابع خودش را با \( n-1 \) صدا می‌زند و \( a \) را به آن ضرب می‌کند.

مراحل محاسبه \( 2^3 \):

- `power_recursive(2, 3)` → ۲ × `power_recursive(2, 2)`

- `power_recursive(2, 2)` → ۲ × `power_recursive(2, 1)`

- `power_recursive(2, 1)` → ۲ × `power_recursive(2, 0)`

- `power_recursive(2, 0)` → ۱

حالا که به \( n = 0 \) رسیدیم، می‌توانیم به عقب برگردیم:

- `power_recursive(2, 1)` = ۲ × ۱ = ۲

- `power_recursive(2, 2)` = ۲ × ۲ = ۴

- `power_recursive(2, 3)` = ۲ × ۴ = ۸

بنابراین، \( 2^3 \) برابر ۸ است.

 

 

مثال محاسبه تعداد اعداد طبیعی تا یک عدد خاص

فرض کنید می‌خواهیم تعداد اعداد طبیعی (۱، ۲، ۳ و ...) را تا یک عدد خاص \( n \) بشماریم. به عنوان مثال، اگر \( n = 5 \)، تعداد اعداد طبیعی از ۱ تا ۵ برابر ۵ خواهد بود.

تابع بازگشتی برای شمارش

حالا می‌توانیم یک تابع بازگشتی برای شمارش اعداد طبیعی تا \( n \) بنویسیم:

def count_numbers(n):
    if n == 0:  # اگر n برابر 0 باشد
        return 0  # هیچ عددی وجود ندارد
    else:
        return 1 + count_numbers(n - 1)  # در غیر این صورت، 1 را به شمارش اعداد طبیعی تا (n-1) اضافه می‌کنیم

چگونه این تابع کار می‌کند:

1. اگر \( n \) برابر ۰ باشد، تابع ۰ را برمی‌گرداند (چون هیچ عددی وجود ندارد).

2. اگر \( n \) بزرگ‌تر از ۰ باشد، تابع خودش را با \( n-1 \) صدا می‌زند و ۱ را به نتیجه اضافه می‌کند.

مراحل محاسبه تعداد اعداد طبیعی تا ۵:

- `count_numbers(5)` → ۱ + `count_numbers(4)`

- `count_numbers(4)` → ۱ + `count_numbers(3)`

- `count_numbers(3)` → ۱ + `count_numbers(2)`

- `count_numbers(2)` → ۱ + `count_numbers(1)`

- `count_numbers(1)` → ۱ + `count_numbers(0)`

- `count_numbers(0)` → ۰

حالا که به \( n = 0 \) رسیدیم، می‌توانیم به عقب برگردیم:

- `count_numbers(1)` = ۱ + ۰ = ۱

- `count_numbers(2)` = ۱ + ۱ = ۲

- `count_numbers(3)` = ۱ + ۲ = ۳

- `count_numbers(4)` = ۱ + ۳ = ۴

- `count_numbers(5)` = ۱ + ۴ = ۵

بنابراین، تعداد اعداد طبیعی تا ۵ برابر ۵ است.

 

معکوس کردن یک عدد

فرض کنید می‌خواهیم معکوس یک عدد طبیعی را محاسبه کنیم. به عنوان مثال، اگر \( n = 1234 \)، معکوس آن \( 4321 \) خواهد بود.

تابع بازگشتی برای معکوس کردن

حالا می‌توانیم یک تابع بازگشتی برای معکوس کردن یک عدد بنویسیم:

def reverse_number(n):
    if n == 0:  # اگر n برابر 0 باشد
        return 0  # معکوس 0 برابر 0 است
    else:
        return str(n % 10) + str(reverse_number(n // 10))  # رقم آخر n را می‌گیریم و معکوس بقیه اعداد را محاسبه می‌کنیم

چگونه این تابع کار می‌کند:

1. اگر \( n \) برابر ۰ باشد، تابع ۰ را برمی‌گرداند (چون معکوس ۰ برابر ۰ است).

2. اگر \( n \) بزرگ‌تر از ۰ باشد، ما آخرین رقم \( n \) را با استفاده از \( n \% 10 \) به دست می‌آوریم و سپس تابع را با عدد بدون آخرین رقم \( n // 10 \) صدا می‌زنیم.

مراحل معکوس کردن \( 1234 \):

- `reverse_number(1234)` → `'4'` + `reverse_number(123)`

- `reverse_number(123)` → `'3'` + `reverse_number(12)`

- `reverse_number(12)` → `'2'` + `reverse_number(1)`

- `reverse_number(1)` → `'1'` + `reverse_number(0)`

- `reverse_number(0)` → `0`

حالا که به \( n = 0 \) رسیدیم، می‌توانیم به عقب برگردیم:

- `reverse_number(1)` = `'1'` + `0` = `'1'`

- `reverse_number(12)` = `'2'` + `'1'` = `'21'`

- `reverse_number(123)` = `'3'` + `'21'` = `'321'`

- `reverse_number(1234)` = `'4'` + `'321'` = `'4321'`

بنابراین، معکوس عدد ۱۲۳۴ برابر ۴۳۲۱ است.