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

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


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

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

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

# استدعِ function
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.

(1) معاملات متعددة

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")

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

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

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
▶ جرّب الكود

الناتج:

TEXT 📖 للعرض فقط
# Function defined successfully


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

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

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

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

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

(1) قيم إرجاع متعددة

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

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}")

(2) كيف يعمل 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
▶ جرّب الكود

الناتج:

TEXT 📖 للعرض فقط
# Function defined successfully

▶ مثال: التحية بمعاملات افتراضية (الصعوبة ⭐)

PYTHON
def greet(name, greeting="Hello", punctuation="!"):
    return f"{greeting}, {name}{punctuation}"

print(greet("Alice"))
print(greet("Bob"))

print(greet("Charlie", greeting="Good morning"))
print(greet("Diana", greeting="Good night", punctuation="~"))

def build_profile(name, age, city="Unknown", hobby="coding"):
    return f"{name}, {age} years old, from {city}, likes {hobby}"

print(build_profile("Alice", 25))
print(build_profile("Bob", 30, city="Shanghai"))
print(build_profile("Charlie", 22, city="Beijing", hobby="painting"))
▶ جرّب الكود

المخرجات:

TEXT 📖 للعرض فقط
Hello, Alice!
Hello, Bob!
Good morning, Charlie!
Good night, Diana~
Alice, 25 years old, from Unknown, likes coding
Bob, 30 years old, from Shanghai, likes coding
Charlie, 22 years old, from Beijing, likes painting


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

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



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



❓ أسئلة شائعة

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

📖 ملخص


📝 تمارين

  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.

Web-Tutorial.com

فريق Web-Tutorial التقني

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

100%