توابع در پایتون: چگونه کدهای قابل استفاده مجدد بنویسیم؟
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 9 دقیقه

توابع در پایتون: چگونه کدهای قابل استفاده مجدد بنویسیم؟

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

اینجاست که توابع (Functions) وارد میدان می‌شوند. توابع به ما اجازه می‌دهند یک بار منطق مورد نیاز را بنویسیم و هر زمان که لازم شد، فقط آن را فراخوانی کنیم. این یعنی:

  • کدهای کوتاه‌تر و خواناتر
  • کاهش خطا و ساده‌تر شدن اشکال‌زدایی
  • امکان استفاده‌ی مجدد از همان کد در پروژه‌های مختلف

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

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

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

def function_name(parameters):
    # بدنه‌ی تابع
    return result
  • function_name: نامی که برای تابع انتخاب می‌کنیم (باید معنادار و توصیفی باشد).
  • parameters: ورودی‌هایی که تابع دریافت می‌کند (اختیاری).
  • return: خروجی‌ای که تابع برمی‌گرداند (اختیاری).

مثال ساده

بیایید یک تابع بنویسیم که دو عدد را جمع کند و نتیجه را برگرداند:

def add_numbers(a, b):
    result = a + b
    return result

print(add_numbers(3, 5))  # خروجی: 8

در این مثال:

  • نام تابع add_numbers است.
  • دو پارامتر a و b دارد.
  • با دستور return حاصل جمع را برمی‌گرداند.

تابع بدون خروجی

گاهی اوقات تابع فقط عملی انجام می‌دهد و نیازی به بازگرداندن مقدار ندارد:

def greet(name):
    print(f"hello {name}!")
    
greet("rookcet")  # خروجی: hello roocket!

این مثال نشان می‌دهد که توابع می‌توانند هم برای محاسبات و هم برای نمایش پیام‌ها یا انجام کارهای دیگر استفاده شوند.

مزایای استفاده از توابع

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

  • کاهش تکرار کد (اصل DRY): با تعریف یک بار تابع، می‌توان آن را بارها و بارها فراخوانی کرد بدون نیاز به نوشتن مجدد همان منطق.

  • افزایش خوانایی و نظم در پروژه: توابع باعث می‌شوند کدها به بخش‌های کوچک‌تر و قابل فهم‌تر تقسیم شوند. این موضوع به‌ویژه در پروژه‌های تیمی اهمیت دارد.

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

  • امکان استفاده‌ی مجدد در پروژه‌های دیگر: توابع خوب طراحی‌شده را می‌توان در فایل‌های جداگانه ذخیره کرد و در پروژه‌های مختلف وارد کرد (import). این یعنی صرفه‌جویی در زمان و انرژی.

  • افزایش انعطاف‌پذیری کد: با استفاده از پارامترها، می‌توان توابعی نوشت که در شرایط مختلف رفتار متفاوتی داشته باشند، بدون نیاز به تغییر در ساختار اصلی تابع.

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

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

1. توابع بدون پارامتر و بدون خروجی

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

def say_hello():
    print("Hello World!")

say_hello()

2. توابع با پارامتر

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

def greet(name):
    print(f"Hello {name}!")

greet("Roocket")

3. توابع با مقدار بازگشتی

توابعی که پس از انجام عملیات، نتیجه را با return برمی‌گردانند.

 def square(x):
    return x * x

result = square(4)
print(result)  # خروجی: 16
 
 

4. توابع داخلی (Built-in Functions)

پایتون مجموعه‌ای از توابع آماده مثل len(), type(), print() دارد که می‌توان بدون تعریف از آن‌ها استفاده کرد.

text = "Roocket"
print(len(text))  # خروجی: 7

5. توابع ناشناس (Lambda Functions)

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

 multiply = lambda a, b: a * b
print(multiply(3, 5))  # خروجی: 15

پارامترها و آرگومان‌ها در توابع پایتون

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

تفاوت پارامتر و آرگومان

  • پارامتر (Parameter): نام متغیرهایی که هنگام تعریف تابع مشخص می‌کنیم.
  • آرگومان (Argument): مقادیری که هنگام فراخوانی تابع به آن ارسال می‌کنیم.
def greet(name):  # name یک پارامتر است
    print(f"سلام {name}!")

greet("roocket")    # "roocket" یک آرگومان است

پارامترهای پیش‌فرض (Default Arguments)

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

def greet(name="مهمان"):
    print(f"سلام {name}!")

greet()           # خروجی: سلام مهمان!
greet("راکت")    # خروجی: سلام راکت!
 

پارامترهای نام‌گذاری‌شده (Keyword Arguments)

در فراخوانی تابع می‌توان نام پارامتر را مشخص کرد تا ترتیب اهمیتی نداشته باشد.

def introduce(name, age):
    print(f"{name}، {age} years old")

introduce(age=30, name="Sara")

پارامترهای متغیر (*args, **kwargs)

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

*args: برای آرگومان‌های موقعیتی

def total(*numbers):
    return sum(numbers)

print(total(1, 2, 3, 4))  # خروجی: 10

 

**kwargs: برای آرگومان‌های کلید-مقدار

def show_info(**info):
    for key, value in info.items():
        print(f"{key}: {value}")

show_info(name="Sara", age=30, job="Developer")

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

محدوده‌ی متغیرها (Scope) در توابع پایتون

در برنامه‌نویسی، هر متغیر فقط در بخشی از برنامه قابل دسترسی است. این بخش را محدوده‌ی متغیر (Scope) می‌نامند. در پایتون، درک درست محدوده‌ها اهمیت زیادی دارد، چون اشتباه در استفاده از متغیرها می‌تواند باعث خطاهای غیرمنتظره شود.

1. متغیرهای محلی (Local Variables)

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

def greet():
    message = "Hello!"
    print(message)

greet()
# print(message)  ← خطا: message خارج از محدوده است

2. متغیرهای سراسری (Global Variables)

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

 name = "Sara"

def greet():
    print(f"Hello {name}!")

greet()  # خروجی: Hello Sara!

3. استفاده از global برای تغییر متغیر سراسری

اگر بخواهیم داخل یک تابع مقدار یک متغیر سراسری را تغییر دهیم، باید از کلیدواژه‌ی global استفاده کنیم.

counter = 0

def increase():
    global counter
    counter += 1

increase()
print(counter)  # خروجی: 1

4. محدوده‌ی تو در تو (Nested Scope)

پایتون از مدل LEGB برای جستجوی متغیرها استفاده می‌کند:

  • L: Local (داخل تابع فعلی)
  • E: Enclosing (توابع تو در تو)
  • G: Global (سطح ماژول)
  • B: Built-in (توابع داخلی پایتون)
def outer():
    x = "بیرونی"
    def inner():
        print(x)  # از محدوده‌ی enclosing استفاده می‌کند
    inner()

outer()

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

بهترین شیوه‌ها برای نوشتن توابع در پایتون

نوشتن تابع فقط به معنای استفاده از def و return نیست؛ بلکه باید به گونه‌ای طراحی شود که قابل فهم، قابل نگهداری و قابل استفاده‌ی مجدد باشد. در ادامه با چند اصل مهم برای نوشتن توابع حرفه‌ای آشنا می‌شویم:

نام‌گذاری معنادار

نام تابع باید دقیقاً نشان دهد که چه کاری انجام می‌دهد. از نام‌های عمومی مثل do_something پرهیز کنید و به جای آن از نام‌هایی مثل calculate_discount یا send_email استفاده کنید.

اصل تک‌وظیفگی (Single Responsibility)

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

استفاده از Docstring

برای هر تابع یک توضیح کوتاه بنویسید تا مشخص شود ورودی‌ها، خروجی‌ها و هدف تابع چیست.

def calculate_area(radius):
    """محاسبه مساحت دایره با استفاده از شعاع"""
    return 3.14 * radius * radius

اجتناب از متغیرهای سراسری

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

تست‌پذیری تابع

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

استفاده از پارامترهای پیش‌فرض و نام‌گذاری‌شده

این کار باعث می‌شود تابع انعطاف‌پذیرتر باشد و خواننده راحت‌تر بتواند آن را فراخوانی کند.

بازاستفاده در ماژول‌های دیگر

اگر تابعی عمومی و کاربردی نوشتید، آن را در یک فایل جداگانه ذخیره کنید و در پروژه‌های دیگر با import استفاده کنید.

رعایت این اصول باعث می‌شود توابع شما نه‌تنها کار کنند، بلکه حرفه‌ای، قابل توسعه و قابل اعتماد باشند.

مثال عملی: مدیریت لیست دانشجویان با توابع

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

تعریف لیست اولیه

students = []

تابع افزودن دانشجو

 def add_student(name):
    students.append(name)
    print(f"{name} با موفقیت اضافه شد.")

تابع نمایش لیست دانشجویان

def show_students():
    print("لیست دانشجویان:")
    for student in students:
        print(f"- {student}")

تابع جستجوی دانشجو

def find_student(name):
    if name in students:
        print(f"{name} در لیست وجود دارد.")
    else:
        print(f"{name} پیدا نشد.")

استفاده از توابع

add_student("Arastoo")
add_student("Sara")
show_students()
find_student("Sara")
find_student("Ali")

خروجی برنامه

Arastoo با موفقیت اضافه شد.
Sara با موفقیت اضافه شد.
لیست دانشجویان:
- Arastoo
- Sara
Sara در لیست وجود دارد.
Ali پیدا نشد.

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

جمع‌بندی

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

با یادگیری موارد زیر، حالا می‌توانید توابع مؤثرتری بنویسید:

  • تعریف تابع با def و استفاده از return
  • انواع توابع: ساده، با پارامتر، با خروجی، lambda و داخلی
  • مدیریت ورودی‌ها با پارامترهای پیش‌فرض، نام‌گذاری‌شده و متغیر
  • شناخت محدوده‌ی متغیرها و مدل LEGB
  • رعایت اصول طراحی تابع: نام‌گذاری، تک‌وظیفگی، Docstring، تست‌پذیری
  • استفاده عملی از توابع در پروژه‌های واقعی مثل مدیریت لیست دانشجویان

توابع پایه‌ی برنامه‌نویسی ماژولار هستند. اگر بتوانید آن‌ها را درست طراحی کنید، نه‌تنها کدتان بهتر کار می‌کند، بلکه قابل توسعه، قابل فهم و قابل اعتماد خواهد بود.

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

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
در انتظار ثبت رای

/@arastoo
ارسطو عباسی
کارشناس تولید و بهینه‌سازی محتوا

...

دیدگاه و پرسش
برای ارسال دیدگاه لازم است وارد شده یا ثبت‌نام کنید ورود یا ثبت‌نام

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

ارسطو عباسی

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