AzLearn

الدوال

Functions

مفهوم ~22 دقيقة

الدوال — Functions

الدوال هي طريقة لتغليف كتلة من الكود تحت اسم واضح يمكن استدعاؤها عند الحاجة. بدون الدوال ستجد نفسك تكرر نفس الكود في أماكن متعددة، وعندما تحتاج تعديلاً ستعدّل في كل مكان على حدة — مع خطر النسيان والأخطاء.

الدالة الجيدة تفعل شيئاً واحداً، تفعله جيداً، ولها اسم يشرح نيّتها.

تعريف دالة بـ def

# تعريف دالة — Define a function
def greet():
    print("مرحباً بالعالم!")

# استدعاء الدالة — Call the function
greet()   # مرحباً بالعالم!

الصيغة: كلمة def ثم اسم الدالة ثم أقواس ثم نقطتان، ثم الكود بمسافة بادئة.

المعاملات — Parameters

الدوال تصبح مفيدة حين تقبل مدخلات تشكّل سلوكها:

# دالة بمعاملات — Function with parameters
def greet(name):
    print(f"مرحباً يا {name}!")

greet("فاطمة")   # مرحباً يا فاطمة!
greet("خالد")    # مرحباً يا خالد!

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

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

introduce("نورة", 24, "الرياض")
introduce("عمر", 30, "جدة")

إرجاع القيم بـ return

الدوال يمكنها حساب شيء وإرجاع النتيجة بدلاً من طباعتها مباشرة:

# دالة ترجع قيمة — Function that returns a value
def add(a, b):
    return a + b

result = add(10, 5)
print(result)   # 15

# يمكن استخدام القيمة المُرجعة في تعبير
total = add(10, 5) + add(3, 7)
print(total)    # 25

الفرق بين print وreturn: print تعرض على الشاشة ولا شيء آخر. return ترجع القيمة ليستخدمها الكود الذي استدعى الدالة. في الكود الاحترافي، الدوال ترجع القيم ولا تطبع مباشرة — هذا يجعلها قابلة للاختبار وقابلة لإعادة الاستخدام.

def calculate_vat(price, rate=0.15):
    return price * rate

# الآن يمكنني استخدام النتيجة بأي طريقة
vat = calculate_vat(200)
total = 200 + vat
print(f"الضريبة: {vat:.2f} ريال")
print(f"الإجمالي: {total:.2f} ريال")
main.go

القيم الافتراضية — Default Arguments

يمكن إعطاء معاملات قيماً افتراضية تُستخدم إذا لم يُمرر شيء:

def greet(name, language="ar"):
    if language == "ar":
        return f"مرحباً يا {name}!"
    else:
        return f"Hello {name}!"

print(greet("سارة"))          # مرحباً يا سارة! — يستخدم الافتراضي
print(greet("Sara", "en"))    # Hello Sara!

القاعدة المهمة: المعاملات ذات القيم الافتراضية يجب أن تأتي بعد المعاملات بدون قيم افتراضية:

# خطأ — Error
def bad(name="x", age):  # SyntaxError!
    pass

# صحيح — Correct
def good(age, name="مجهول"):
    pass

المعاملات بالاسم — Keyword Arguments

عند الاستدعاء يمكن تسمية المعاملات لتوضيح المقصود:

def create_user(username, email, role="user", active=True):
    return f"أنشأت: {username} ({role})"

# بالترتيب — Positional
result1 = create_user("ahmed", "[email protected]")

# بالاسم — Keyword (أوضح)
result2 = create_user(
    username="sara",
    email="[email protected]",
    role="admin",
    active=True
)

*args و**kwargs — المعاملات المرنة

*args تسمح بتمرير عدد غير محدد من المعاملات:

# *args — عدد غير محدد من الأرقام
def sum_all(*numbers):
    total = 0
    for n in numbers:
        total += n
    return total

print(sum_all(1, 2, 3))         # 6
print(sum_all(10, 20, 30, 40))  # 100

**kwargs تسمح بتمرير عدد غير محدد من المعاملات بالاسم:

# **kwargs — معاملات مسماة غير محدودة
def print_info(**details):
    for key, value in details.items():
        print(f"  {key}: {value}")

print_info(name="عزيز", city="المدينة", role="مطور")
main.go

النطاق — Scope (LEGB)

Python تبحث عن المتغيرات بهذا الترتيب: L → E → G → B (Local → Enclosing → Global → Built-in)

# نطاق المتغيرات — Variable scope
name = "عالمي"  # متغير عام — Global variable

def show():
    name = "محلي"   # متغير محلي — Local variable
    print(name)     # "محلي" — يرى المحلي أولاً

show()          # محلي
print(name)     # عالمي — لم يتغير الخارجي

المتغير المحلي لا يؤثر على العام ولا يُرى خارج الدالة. هذا العزل مقصود — يجعل الدوال آمنة ويمنع تعارض المتغيرات.

التوثيق بـ Docstrings

الدالة الجيدة تشرح نفسها في سطر أو سطرين:

def calculate_vat(price, rate=0.15):
    """
    احسب ضريبة القيمة المضافة.

    price: السعر قبل الضريبة (float)
    rate: نسبة الضريبة، الافتراضي 15% (float)
    returns: مبلغ الضريبة (float)
    """
    return price * rate

help(calculate_vat) ستعرض هذا التوثيق. يمكنك أيضاً الوصول إليه بـ calculate_vat.__doc__.

main.go
تحدي — Challenge

خلاصة

الدوال هي الطريقة الرئيسية لتنظيم الكود في Python. الدالة الجيدة: لها اسم واضح يصف ما تفعله، تقبل مدخلات عبر المعاملات، وترجع نتيجة بدلاً من الطباعة المباشرة. استخدم القيم الافتراضية لجعل الدالة مرنة، والـ docstring لتوثيقها. في الدرس القادم ستجمع كل ما تعلمته لبناء برنامج متكامل لحساب الفواتير.