البرمجة📅 2026-09-2312 دقائق قراءة
الدوال (Functions) في Python — نظّم كودك باحتراف

الدوال (Functions) في Python — نظّم كودك باحتراف

دليل شامل لتعلم الدوال في Python — تعريف الدوال، المعاملات، القيم المُرجعة، الدوال المجهولة، مع مشاريع تطبيقية خطوة بخطوة

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

هنا يأتي دور الدوال (Functions) — التي تحوّل كودك من فوضى إلى هيكل منظم وقابل للتوسع.

بنهاية هذا المقال، ستكون قادراً على:

  • تعريف دوالك الخاصة باستخدام def
  • تمرير المعاملات (Parameters) واستقبال الوسائط (Arguments)
  • إرجاع القيم (Return) من الدوال
  • فهم نطاق المتغيرات (Scope)
  • استخدام الدوال المجهولة (Lambda)
  • بناء مشاريع منظمة باستخدام الدوال

1. ما هي الدوال ولماذا نحتاجها؟

التعريف

الدالة (Function) هي كتلة من الكود لها اسم محدد، تؤدي مهمة معينة، ويمكن استدعاؤها عدة مرات.

القياس العملي

تخيل أنك في مطعم. بدلاً من أن تشرح للطاهي كل خطوة لإعداد الطبق، تقول فقط: "أريد بيتزا". الطاهي يعرف ما يجب فعله.

الدالة هي مثل الطاهي — تعطيها "الطلب" (المعاملات)، وتعيد لك "الطبق" (القيمة المُرجعة).

المشكلة: كود مكرر

# بدون دوال — كود مكرر
name1 = "أحمد"
print(f"مرحباً {name1}!")
print(f"أهلاً بك في الموقع")
print()

name2 = "سارة"
print(f"مرحباً {name2}!")
print(f"أهلاً بك في الموقع")
print()

name3 = "محمد"
print(f"مرحباً {name3}!")
print(f"أهلاً بك في الموقع")

المشكلة: نفس الكود مكرر 3 مرات!

الحل: استخدام دالة

# مع دالة — كود نظيف
def welcome(name):
    print(f"مرحباً {name}!")
    print(f"أهلاً بك في الموقع")
    print()

welcome("أحمد")
welcome("سارة")
welcome("محمد")

النتيجة: نفس النتيجة بكود أقل وأنظف!

فوائد الدوال

الفائدةالشرح
إعادة الاستخداماكتب مرة، استخدم مرات لا نهائية
تنظيم الكودكل دالة لها مهمة واحدة واضحة
سهولة الصيانةتعديل واحد يؤثر على كل الاستخدامات
سهولة الاختباريمكن اختبار كل دالة على حدة
قراءة أفضلالكود يشرح نفسه بأسماء الدوال

2. تعريف الدوال باستخدام def

الصيغة الأساسية

def اسم_الدالة():
    # الكود الذي تنفذه الدالة

⚠️ ملاحظات مهمة:

  • تبدأ الكلمة المفتاحية def (اختصار define)
  • اسم الدالة يتبع نفس قواعد أسماء المتغيرات
  • تنتهي بنقطتين :
  • الكود داخلها مُزاح (Indented)

أول دالة لك

def greet():
    print("مرحباً بك!")
    print("أهلاً وسهلاً")

# استدعاء الدالة
greet()
greet()

النتيجة:

مرحباً بك!
أهلاً وسهلاً
مرحباً بك!
أهلاً وسهلاً

⚠️ ملاحظة مهمة: تعريف مقابل استدعاء

# هذا تعريف — لا ينفذ أي شيء بعد
def greet():
    print("مرحباً")

# هذا استدعاء — هنا يُنفذ الكود
greet()

القاعدة: تعريف الدالة لا ينفذ شيئاً. يجب استدعاؤها بالاسم مع ().

دالة بدون معاملات

def show_menu():
    print("=" * 30)
    print("📋 قائمة المطعم")
    print("=" * 30)
    print("1. بيتزا")
    print("2. برجر")
    print("3. شاورما")
    print("=" * 30)

show_menu()

النتيجة:

==============================
📋 قائمة المطعم
==============================
1. بيتزا
2. برجر
3. شاورما
==============================

3. المعاملات (Parameters) والوسائط (Arguments)

الفرق بينهما

المصطلحالمعنىالمثال
Parameter (معامل)المتغير في تعريف الدالةdef greet(name):
Argument (وسيط)القيمة المرسلة عند الاستدعاءgreet("أحمد")

دالة بمعامل واحد

def greet(name):
    print(f"مرحباً {name}!")

greet("أحمد")
greet("سارة")
greet("محمد")

النتيجة:

مرحباً أحمد!
مرحباً سارة!
مرحباً محمد!

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

def introduce(name, age, city):
    print(f"اسمي {name}")
    print(f"عمري {age} سنة")
    print(f"أسكن في {city}")
    print("-" * 20)

introduce("أحمد", 25, "عمّان")
introduce("سارة", 30, "دبي")

النتيجة:

اسمي أحمد
عمري 25 سنة
أسكن في عمّان
--------------------
اسمي سارة
عمري 30 سنة
أسكن في دبي
--------------------

⚠️ عدد الوسائط يجب أن يطابق

def greet(name):
    print(f"مرحباً {name}!")

# خطأ — دالة تتوقع معاملاً واحداً
greet()       # TypeError
greet("أحمد", "محمد")  # TypeError

الخطأ: TypeError: greet() missing 1 required positional argument

4. أنواع المعاملات

1. معاملات افتراضية (Default Parameters)

def greet(name, greeting="مرحباً"):
    print(f"{greeting} {name}!")

greet("أحمد")
greet("سارة", "أهلاً")
greet("محمد", "صباح الخير")

النتيجة:

مرحباً أحمد!
أهلاً سارة!
صباح الخير محمد!

القاعدة: المعاملات الافتراضية تأتي في نهاية القائمة.

# خطأ — المعامل الافتراضي قبل الإلزامي
def greet(greeting="مرحباً", name):  # SyntaxError
    print(f"{greeting} {name}")

# صحيح
def greet(name, greeting="مرحباً"):
    print(f"{greeting} {name}")

2. معاملات بالاسم (Keyword Arguments)

def introduce(name, age, city):
    print(f"{name}، {age} سنة، من {city}")

# بدون أسماء — يجب الترتيب
introduce("أحمد", 25, "عمّان")

# بالأسماء — الترتيب حر
introduce(age=25, city="عمّان", name="أحمد")

النتيجة: كلاهما يعطي نفس النتيجة.

الفائدة: الكود أوضح، لا حاجة لتذكر الترتيب.

3. عدد متغير من المعاملات (*args)

def sum_all(*numbers):
    total = 0
    for num in numbers:
        total += num
    return total

print(sum_all(1, 2, 3))
print(sum_all(10, 20, 30, 40, 50))

النتيجة:

6
150

شرح: *numbers يستقبل أي عدد من الوسائط كـ tuple.

4. معاملات مسماة متغيرة (**kwargs)

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

print_info(name="أحمد", age=25, city="عمّان")

النتيجة:

name: أحمد
age: 25
city: عمّان

شرح: **info يستقبل أي عدد من الوسائط المسماة كـ dictionary.

5. القيم المُرجعة (Return)

ما هي return؟

return تُنهي الدالة وتُرجع قيمة للمُستدعي.

دالة بدون return

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

result = add(3, 5)
print(f"النتيجة: {result}")

النتيجة:

8
النتيجة: None

لاحظ: result يساوي None — لأن الدالة لا ترجع شيئاً.

دالة مع return

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

result = add(3, 5)
print(f"النتيجة: {result}")

النتيجة:

النتيجة: 8

الفرق بين print و return

العنصرprintreturn
الوظيفةيعرض على الشاشةيُرجع قيمة للمُستدعي
يمكن استخدامها؟لا — فقط عرضنعم — في عمليات أخرى
مثالprint(5+3) → 8return 5+3 → قيمة 8
الاستخدامللعرض النهائيللحسابات والمنطق

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

def calculate(a, b):
    total = a + b
    difference = a - b
    product = a * b
    return total, difference, product

t, d, p = calculate(10, 3)
print(f"المجموع: {t}")
print(f"الفرق: {d}")
print(f"الضرب: {p}")

النتيجة:

المجموع: 13
الفرق: 7
الضرب: 30

ملاحظة: Python ترجع القيم كـ tuple.

return تُنهي الدالة

def check_age(age):
    if age < 0:
        return "عمر غير صالح"
    
    if age < 18:
        return "قاصر"
    
    return "بالغ"

print(check_age(-5))
print(check_age(15))
print(check_age(25))

النتيجة:

عمر غير صالح
قاصر
بالغ

مهم: بعد return، لا ينفذ أي كود في الدالة.

def test():
    print("هذا يُنفذ")
    return "القيمة"
    print("هذا لن يُنفذ أبداً")

print(test())

النتيجة:

هذا يُنفذ
القيمة

6. نطاق المتغيرات (Variable Scope)

المتغيرات المحلية (Local)

def my_function():
    x = 10    # متغير محلي
    print(x)

my_function()
print(x)   # خطأ!

الخطأ: NameError: name 'x' is not defined

السبب: x موجود فقط داخل الدالة.

المتغيرات العامة (Global)

x = 10    # متغير عام

def my_function():
    print(x)   # يمكن قراءته

my_function()   # النتيجة: 10
print(x)        # النتيجة: 10

الفرق بين القراءة والتعديل

counter = 0

def increment():
    global counter   # يجب استخدام global للتعديل
    counter += 1

increment()
increment()
print(counter)

النتيجة:

2

⚠️ تحذير: استخدام global غير مُفضل — يسبب مشاكل في المشاريع الكبيرة.

القاعدة الذهبية

مرر ما تحتاجه، وأرجع ما تنتجه. لا تستخدم global.

# ❌ سيء
counter = 0
def increment():
    global counter
    counter += 1

# ✅ جيد
def increment(counter):
    return counter + 1

counter = 0
counter = increment(counter)
counter = increment(counter)
print(counter)   # النتيجة: 2

7. الدوال المدمجة (Built-in Functions)

Python تأتي مع عشرات الدوال الجاهزة:

الدالةالوظيفةمثال
len()طول العنصرlen("Python") → 6
max()أكبر قيمةmax(1, 5, 3) → 5
min()أصغر قيمةmin(1, 5, 3) → 1
sum()مجموع العناصرsum([1,2,3]) → 6
abs()القيمة المطلقةabs(-5) → 5
round()التقريبround(3.7) → 4
sorted()ترتيبsorted([3,1,2]) → [1,2,3]
type()نوع العنصرtype(5) → <class 'int'>

8. الدوال المجهولة (Lambda)

ما هي Lambda؟

lambda هي طريقة مختصرة لكتابة دالة صغيرة في سطر واحد.

الصيغة

lambda parameters: expression

مثال مقارنة

الدالة العادية:

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

print(add(3, 5))

الدالة المجهولة:

add = lambda a, b: a + b
print(add(3, 5))

النتيجة: كلاهما يعطي 8.

متى تستخدم lambda؟

استخدمها عندما:

  • الدالة بسيطة جداً (سطر واحد)
  • ستُستخدم مرة واحدة فقط
  • مع sorted() أو map() أو filter()

مثال عملي:

# ترتيب أسماء حسب الطول
names = ["أحمد", "محمد عبد الرحمن", "سارة", "خالد إبراهيم"]

# بدون lambda
def get_length(name):
    return len(name)

sorted_names = sorted(names, key=get_length)
print(sorted_names)

# مع lambda (أنظف)
sorted_names = sorted(names, key=lambda n: len(n))
print(sorted_names)

9. Docstrings — توثيق الدوال

ما هي Docstring؟

نص توضيحي داخل الدالة يشرح وظيفتها. يُكتب بين ثلاث علامات تنصيص.

def calculate_area(length, width):
    """
    تحسب مساحة المستطيل.
    
    المعاملات:
        length (float): الطول
        width (float): العرض
    
    العائد:
        float: مساحة المستطيل
    """
    return length * width

# يمكن عرض التوثيق
print(calculate_area.__doc__)

فائدة: يمكنك قراءة التوثيق بـ help() أو .__doc__.

10. مشاريع عملية

المشروع 1: آلة حاسبة باستخدام الدوال

# آلة حاسبة منظمة باستخدام الدوال

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 "❌ لا يمكن القسمة على صفر"
    return a / b

def show_menu():
    """عرض القائمة"""
    print("\n" + "=" * 30)
    print("🧮 آلة حاسبة")
    print("=" * 30)
    print("1. جمع")
    print("2. طرح")
    print("3. ضرب")
    print("4. قسمة")
    print("5. خروج")
    print("=" * 30)

def calculator():
    """الدالة الرئيسية للآلة الحاسبة"""
    while True:
        show_menu()
        choice = input("اختر العملية (1-5): ")
        
        if choice == "5":
            print("👋 وداعاً!")
            break
        
        if choice not in ["1", "2", "3", "4"]:
            print("❌ اختيار غير صحيح")
            continue
        
        try:
            a = float(input("الرقم الأول: "))
            b = float(input("الرقم الثاني: "))
        except ValueError:
            print("❌ يرجى إدخال أرقام صحيحة")
            continue
        
        if choice == "1":
            print(f"النتيجة: {add(a, b)}")
        elif choice == "2":
            print(f"النتيجة: {subtract(a, b)}")
        elif choice == "3":
            print(f"النتيجة: {multiply(a, b)}")
        elif choice == "4":
            print(f"النتيجة: {divide(a, b)}")

# تشغيل الآلة الحاسبة
calculator()

المشروع 2: نظام إدارة المهام

# نظام إدارة مهام منظم بالدوال

tasks = []

def add_task(title):
    """إضافة مهمة جديدة"""
    task = {"title": title, "done": False}
    tasks.append(task)
    print(f"✅ تمت إضافة: {title}")

def list_tasks():
    """عرض جميع المهام"""
    if not tasks:
        print("📭 لا توجد مهام")
        return
    
    print("\n📋 قائمة المهام:")
    print("-" * 40)
    for i, task in enumerate(tasks, 1):
        status = "✅" if task["done"] else "⏳"
        print(f"{i}. {status} {task['title']}")
    print("-" * 40)

def complete_task(index):
    """إكمال مهمة"""
    if 1 <= index <= len(tasks):
        tasks[index - 1]["done"] = True
        print(f"🎉 تم إكمال: {tasks[index - 1]['title']}")
    else:
        print("❌ رقم المهمة غير صحيح")

def delete_task(index):
    """حذف مهمة"""
    if 1 <= index <= len(tasks):
        removed = tasks.pop(index - 1)
        print(f"🗑️ تم حذف: {removed['title']}")
    else:
        print("❌ رقم المهمة غير صحيح")

# تجربة النظام
add_task("تعلم Python")
add_task("بناء مشروع")
add_task("قراءة كتاب")
list_tasks()
complete_task(1)
list_tasks()

المشروع 3: مكتبة حسابات رياضية

# مكتبة حسابات رياضية باستخدام الدوال

def square(n):
    """مربع الرقم"""
    return n ** 2

def cube(n):
    """مكعب الرقم"""
    return n ** 3

def is_even(n):
    """هل الرقم زوجي؟"""
    return n % 2 == 0

def is_prime(n):
    """هل الرقم أولي؟"""
    if n < 2:
        return False
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            return False
    return True

def factorial(n):
    """مضروب الرقم"""
    if n < 0:
        return None
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result

# اختبار الدوال
print(f"مربع 5: {square(5)}")
print(f"مكعب 3: {cube(3)}")
print(f"هل 4 زوجي؟ {is_even(4)}")
print(f"هل 7 أولي؟ {is_prime(7)}")
print(f"مضروب 5: {factorial(5)}")

11. أخطاء شائعة

الخطأ 1: نسيان الأقواس عند الاستدعاء

def greet():
    print("مرحباً")

# خطأ — لا ينفذ الدالة
greet

# صحيح
greet()

الخطأ 2: نسيان return

# خطأ
def add(a, b):
    result = a + b
    # نسيت return

print(add(3, 5))   # None

# صحيح
def add(a, b):
    return a + b

الخطأ 3: استخدام متغير محلي خارج الدالة

def calculate():
    x = 10

calculate()
print(x)   # NameError

الخطأ 4: ترتيب خاطئ للمعاملات الافتراضية

# خطأ
def greet(greeting="مرحباً", name):
    print(f"{greeting} {name}")

# صحيح
def greet(name, greeting="مرحباً"):
    print(f"{greeting} {name}")

الخطأ 5: تعديل قائمة افتراضية

# خطأ — القائمة الافتراضية تُنشأ مرة واحدة فقط!
def add_item(item, items=[]):
    items.append(item)
    return items

print(add_item("أ"))   # ['أ']
print(add_item("ب"))   # ['أ', 'ب'] — مشكلة!

# صحيح
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

12. تمارين عملية

التمرين 1: دالة المساحة

اكتب دالة circle_area(radius) تحسب مساحة الدائرة (π × r²).

التمرين 2: دالة الترحيب

اكتب دالة welcome(name, time) تطبع:

  • "صباح الخير [الاسم]" إذا كان time = "morning"
  • "مساء الخير [الاسم]" إذا كان time = "evening"

التمرين 3: دالة الأكبر

اكتب دالة find_max(numbers) تأخذ قائمة وتُرجع أكبر رقم.

التمرين 4: دالة التصفية

اكتب دالة filter_even(numbers) تُرجع قائمة بالأرقام الزوجية فقط.

التمرين 5: دالة الحساب المتكامل

اكتب دالة calculate_grade(score) تُرجع:

  • 90+ : "ممتاز"
  • 80-89 : "جيد جداً"
  • 70-79 : "جيد"
  • 60-69 : "مقبول"
  • أقل من 60 : "راسب"

قائمة تحقق — هل تعلمت؟

المهارةالحالة
تعريف الدوال باستخدام def
تمرير المعاملات واستقبال الوسائط
استخدام المعاملات الافتراضية
إرجاع القيم باستخدام return
فهم نطاق المتغيرات (Local / Global)
استخدام *args و **kwargs
كتابة الدوال المجهولة (Lambda)
كتابة Docstrings للتوثيق
بناء مشاريع منظمة بالدوال

الخلاصة

في هذا المقال، تعلمت:

  1. تعريف الدوال — باستخدام def
  2. المعاملات والوسائط — تمرير البيانات للدوال
  3. القيم المُرجعة — إرجاع النتائج بـ return
  4. نطاق المتغيرات — Local و Global
  5. الدوال المدمجة — الجاهزة في Python
  6. الدوال المجهولة (Lambda) — للدوال القصيرة
  7. Docstrings — توثيق الدوال
  8. المشاريع — تطبيق كل ما تعلمته

الدوال هي حجر الأساس للبرمجة الاحترافية — بدونها، مشاريعك ستبقى فوضى صغيرة.

في المقال القادم: سنتطبق كل ما تعلمناه في 5 مشاريع Python للمبتدئين — لتبني أول أعمالك الحقيقية!

جرب التمارين الخمسة قبل الانتقال للمقال التالي. الممارسة هي المفتاح!

ما نوع الدالة التي استمتعت بكتابتها؟ شاركنا في التعليقات!

فريق نهضة

فريق نهضة

فريق عربي متخصص في التقنية والذكاء الاصطناعي وتطوير الذات

📚 مقالات ذات صلة

الحلقات في Python — كرر المهام بذكاء
البرمجة

الحلقات في Python — كرر المهام بذكاء

دليل شامل لتعلم الحلقات في Python — for و while و range و break و continue مع مشاريع تفاعلية خطوة بخطوة

الشروط في Python — كيف تجعل برنامجك يتخذ قرارات؟
البرمجة

الشروط في Python — كيف تجعل برنامجك يتخذ قرارات؟

دليل شامل لتعلم الشروط في Python — if, else, elif والعوامل المنطقية مع أمثلة عملية ومشاريع تفاعلية خطوة بخطوة

أول برنامج لك بلغة Python — Hello World وأكثر
البرمجة

أول برنامج لك بلغة Python — Hello World وأكثر

دليل عملي لكتابة أول برنامج Python — تعلم print و input والمتغيرات والتعليقات مع أمثلة تفاعلية خطوة بخطوة