الدوال الأساسية

حتى الآن، كان كودك يُنفّذ سطراً بسطر. لكن ماذا لو كنت بحاجة لإعادة استخدام نفس الوظيفة؟ نسخ ولصق كل مرة؟ الدوال تحل هذه المشكلة — ضع كتلة من الكود، أعطها اسماً، واستدعها عندما تحتاج. هذه هي الخطوة الأولى من "كتابة الكود" إلى "تنظيم الكود."


1. ما هي الدالة

الدالة هي كتلة مسماة من الكود يمكنك استدعاؤها في أي وقت.

PYTHON
# عرّف دالة
def say_hello():
    print("Hello!")
    print("Welcome to Python!")

# استدعِ الدالة
say_hello()
say_hello()      # يمكن استدعاؤها عدة مرات

المخرجات:

TEXT
Hello!
Welcome to Python!
Hello!
Welcome to Python!
💡 لماذا نستخدم الدوال؟ 1) تجنب تكرار الكود (DRY = Don't Repeat Yourself). 2) الكود أسهل في الفهم — اسم دالة جيد أكثر فائدة من تعليق كبير. 3) عدّل في مكان واحد، جميع الاستدعاءات تتحدّث تلقائياً.


2. المعاملات: تمرير البيانات إلى الدوال

يمكن للدوال أن تقبل معاملات لجعلها أكثر مرونة:

PYTHON
def greet(name):
    """ألقِ التحية على شخص باسمه"""
    print(f"Hello, {name}! Welcome to Python.")

greet("Zhang San")     # Hello, Zhang San! Welcome to Python.
greet("Li Si")         # Hello, Li Si! Welcome to Python.

معاملات متعددة

PYTHON
def introduce(name, age, city):
    print(f"My name is {name}, I'm {age} years old, from {city}.")

introduce("Zhang San", 25, "Beijing")
introduce("Li Si", 30, "Shanghai")

ترتيب المعاملات: الوسائط الموضعية

عند استدعاء دالة، تُطابَق الوسائط حسب الموضع:

PYTHON
def create_user(name, age, is_admin):
    print(f"Creating user: {name}, Age: {age}, Admin: {is_admin}")

create_user("Zhang San", 25, False)    # تُطابَق حسب الترتيب
create_user(False, "Zhang San", 25)    # ترتيب خاطئ — غير متطابق!

مثال: دوال الآلة الحاسبة (الصعوبة ⭐)

PYTHON
def add(a, b):
    print(f"{a} + {b} = {a + b}")

def multiply(a, b):
    print(f"{a} * {b} = {a * b}")

add(5, 3)          # 5 + 3 = 8
multiply(5, 3)     # 5 * 3 = 15
▶ جرّب الكود

3. قيم الإرجاع

يمكن للدوال استخدام return لإرسال نتيجة إلى المتصل:

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

result = add(5, 3)
print(result)               # 8

# قيم الإرجاع يمكن استخدامها مباشرة في التعبيرات
total = add(10, 20) + add(30, 40)
print(total)                # 100
⚠️ ملاحظة:إذا كانت الدالة لا تحتوي على return، تُرجع None. هذا مختلف عن "لا قيمة إرجاع" — إنها تُرجع شيئاً، فقط None.

قيم إرجاع متعددة

يمكن لبايثون إرجاع قيم متعددة في وقت واحد (أساساً تُرجع صفاً):

PYTHON
def get_min_max(numbers):
    return min(numbers), max(numbers)

result = get_min_max([3, 1, 4, 1, 5])
print(result)               # (1, 5)

# فكّك النتيجة مباشرة
low, high = get_min_max([3, 1, 4, 1, 5])
print(f"Min: {low}, Max: {high}")

كيف يعمل return

return ينهي تنفيذ الدالة فوراً؛ الكود بعده لن يُنفّذ:

PYTHON
def check_age(age):
    if age < 0:
        return "Age cannot be negative!"    # إرجاع مبكر
    if age < 18:
        return "Minor"
    return "Adult"

print(check_age(-5))     # Age cannot be negative!
print(check_age(15))     # Minor
print(check_age(25))     # Adult

مثال: أداة تحويل درجة الحرارة (الصعوبة ⭐⭐)

PYTHON
def celsius_to_fahrenheit(c):
    """حوّل مئوي إلى فهرنهايت"""
    return c * 9 / 5 + 32

def fahrenheit_to_celsius(f):
    """حوّل فهرنهايت إلى مئوي"""
    return (f - 32) * 5 / 9

# اختبار
print(f"0°C = {celsius_to_fahrenheit(0):.1f}°F")      # 32.0°F
print(f"100°C = {celsius_to_fahrenheit(100):.1f}°F")   # 212.0°F
print(f"32°F = {fahrenheit_to_celsius(32):.1f}°C")     # 0.0°C
print(f"212°F = {fahrenheit_to_celsius(212):.1f}°C")   # 100.0°C
▶ جرّب الكود

4. سلاسل التوثيق (Docstrings)

التعليق على السطر الأول بعد تعريف الدالة، المكتوب بـ """، هو سلسلة التوثيق — تشرح ما تفعله الدالة:

PYTHON
def calculate_bmi(weight, height):
    """
    احسب مؤشر كتلة الجسم (BMI)

    المعاملات:
        weight (float): وزن الجسم بالكيلوغرام
        height (float): طول الجسم بالمتر

    تُرجع:
        float: قيمة BMI
    """
    return weight / (height ** 2)

# عرض سلسلة التوثيق
print(calculate_bmi.__doc__)
help(calculate_bmi)
💡 عادة جيدة: اكتب سلسلة توثيق عند إنشاء دالة، حتى لو كانت سطراً واحداً. بدونها: 1) help(your_function) لا يُظهر شيئاً؛ 2) بعد شهرين، حتى أنت لن تتذكر ما تفعله الدالة. التنسيق ليس إلزامياً، لكن يُوصى بتضمين وصف المعاملات و وصف القيمة المُرجعة.


5. مكدس استدعاء الدوال

عندما تستدعي دالة دالة أخرى، تحتفظ بايثون بـ "مكدس استدعاء" في الذاكرة:

PYTHON
def a():
    print("Entering a")
    b()
    print("Exiting a")

def b():
    print("Entering b")
    c()
    print("Exiting b")

def c():
    print("Entering c")
    print("Exiting c")

a()

المخرجات:

TEXT
Entering a
Entering b
Entering c
Exiting c
Exiting b
Exiting a

مثل كومة من الأطباق — آخر ما يوضع هو أول ما يؤخذ. هذا الهيكل "آخر ما يدخل، أول ما يخرج" يُسمى مكدساً. استدعاءات الدوال المتداخلة بعمق يمكن أن تسبب "فيضاً في المكدس" (مثل العودية بدون شرط إنهاء).


حالات الاستخدام الشائعة


❓ أسئلة شائعة

س ما الفرق بين return و print()؟
ج return يُرسل النتيجة إلى المتصل؛ print() فقط يعرض المخرجات على وحدة التحكم. الدالة تحتاج return لتمرير قيمة إلى الخارج. مع print()، يمكنك فقط رؤيتها — لا يمكنك استخدامها. س:هل يمكن للدالة أن تحتوي على عدة جمل return؟ ج:نعم. يمكن للدالة أن تحتوي على عدة جمل return، لكن فقط أول واحدة تُصادف ستُنفّذ — إنهاء فوري للدالة. هذا شائع في المنطق الشرطي: شروط مختلفة تُرجع قيماً مختلفة. س:هل يجب أن تحتوي الدالة على معاملات؟ ج:لا. الدوال بدون معاملات صالحة تماماً. مثلاً، def get_current_time(): لا تحتاج معاملات وتُرجع الوقت الحالي مباشرة (باستخدام وحدة datetime). عدد المعاملات يعتمد على ما إذا كانت الدالة تحتاج بيانات خارجية.

📖 ملخص

  • الدوال تُعرّف بـ def، تضم الكود في كتل مسماة قابلة لإعادة الاستخدام
  • المعاملات تجعل الدوال مرنة؛ تُطابَق حسب الموضع
  • return يُرسل النتيجة وينهي الدالة؛ قيم الإرجاع المتعددة هي أساساً صف
  • الدوال بدون return تُرجع None
  • سلاسل التوثيق تستخدم """ لوصف الدوال؛ تُعرض بـ help()
  • مكدس استدعاء الدوال هو هيكل آخر ما يدخل أول ما يخرج؛ التداخل العميق يمكن أن يسبب فيضاً في المكدس

📝 تمارين

  1. مبتدئ (الصعوبة ⭐): اكتب دالة is_even(n) تأخذ عدداً صحيحاً وتُرجع True إذا كان زوجياً، False إذا كان فردياً. استخدم عامل %.

  2. متوسط (الصعوبة ⭐⭐): اكتب دالة grade(score) تأخذ درجة (0-100) وتُرجع تقدير الحرف المقابل: 90+ يُرجع "A"، 80-89 يُرجع "B"، 70-79 يُرجع "C"، 60-69 يُرجع "D"، أقل من 60 يُرجع "F". استخدم if-elif للتنفيذ.

  3. متقدم (الصعوبة ⭐⭐⭐): اكتب ثلاث دوال add() و subtract() و multiply(). ثم اكتب دالة رابعة calculate(a, b, operator) تأخذ رقمين وسلسلة عامل ("+"، "-"، "*")، تستدعي الدالة المقابلة، وتُرجع النتيجة. إذا كان العامل غير مدعوم، أرجع None.

100%