تمرير المعاملات (Parameters) واسترجاع القيم (Return) بكفاءة


ماذا سنتعلم؟ سنتعمق اليوم في كيفية تمرير المعاملات (Parameters) إلى الدوال واسترجاع القيم (Return) منها بفعالية، مما يعزز من مرونة وقابلية إعادة استخدام الكود.

سنستكشف أفضل الممارسات والتقنيات المتقدمة لجعل دوالنا أكثر قوة وقدرة على التكيف مع سيناريوهات مختلفة.

الخطوة 1: أساسيات الدوال وتمرير المعاملات الموضعية

تعتبر الدوال اللبنة الأساسية لتنظيم الكود. عند تعريف دالة، يمكننا تحديد المعاملات التي ستقبلها. يتم تمرير المعاملات الموضعية بناءً على ترتيبها.

ملاحظة تقنية: المعاملات الموضعية (Positional Arguments) هي الأسهل استخداماً وتعتمد على ترتيب تمرير القيم للدالة.
def greet_user(name):
    # تعريف دالة بسيطة تستقبل معامل واحد هو الاسم
    return f"أهلاً بك يا {name}!" # ترجع رسالة ترحيبية

# استدعاء الدالة وتمرير معامل موضعي
message = greet_user("أحمد")
print(message)

في هذا الجزء، قمنا بتعريف دالة greet_user تستقبل name كمعامل. عند استدعائها، يتم تمرير القيمة "أحمد" إلى name.

الخطوة 2: تمرير معاملات متعددة وأنواع مختلفة (مفاتيح، افتراضية، متغيرة)

لزيادة مرونة الدوال، يمكننا استخدام معاملات بمفاتيح (Keyword Arguments)، معاملات افتراضية (Default Arguments)، ومعاملات متغيرة العدد (Variable-length Arguments).

ملاحظة تقنية: استخدام المعاملات الافتراضية يجعل المعامل اختيارياً، بينما *args و **kwargs يسمحان للدالة بقبول أي عدد من المعاملات الموضعية أو معاملات المفاتيح على التوالي.
def calculate_area(length, width=10):
    # دالة لحساب المساحة بمعامل افتراضي للعرض
    # إذا لم يتم تمرير العرض، فسيتم استخدام القيمة الافتراضية 10
    return length * width

def process_data(data_id, *args, **kwargs):
    # دالة لمعالجة البيانات تستقبل معرف، ثم عدد غير محدد من المعاملات الموضعية (*args)
    # وعدد غير محدد من معاملات المفاتيح (**kwargs)
    print(f"معرف البيانات: {data_id}")
    print(f"البيانات الإضافية (موضعية): {args}") # *args تجمع المعاملات الموضعية كـ tuple
    print(f"الخيارات الإضافية (مفاتيح): {kwargs}") # **kwargs تجمع معاملات المفاتيح كـ dictionary

# استدعاء الدالة بمعامل افتراضي
area1 = calculate_area(5) # الطول 5، العرض سيستخدم الافتراضي (10)
print(f"المساحة مع عرض افتراضي: {area1}")

# استدعاء الدالة بمعاملات مفاتيح
area2 = calculate_area(length=7, width=3) # تحديد الطول والعرض صراحةً باستخدام المفاتيح
print(f"المساحة مع عرض محدد: {area2}")

# استدعاء الدالة بمعاملات متغيرة
process_data(101, "item1", "item2", status="active", priority="high")

هنا، calculate_area توضح كيف يمكن للعرض أن يكون اختيارياً. أما process_data فتستعرض قوة *args و **kwargs في التعامل مع عدد غير معروف من المعاملات.

الخطوة 3: استرجاع القيم بكفاءة (قيمة واحدة، قيم متعددة Tuple)

يمكن للدالة أن ترجع قيمة واحدة أو عدة قيم. عندما ترجع الدالة قيم متعددة، فإنها تقوم بذلك عادةً على هيئة tuple.

ملاحظة تقنية: ترجيع قيم متعددة كـ tuple هو طريقة فعالة لتجميع النتائج ذات الصلة دون الحاجة لإنشاء كائنات معقدة أو تمريرها كمعاملات "out".
def get_user_info(user_id):
    # دالة تحاكي جلب بيانات المستخدم
    if user_id == 1:
        return "علي", 30, "مطور برمجيات" # ترجع ثلاث قيم كـ tuple
    else:
        return None, None, None # ترجع None لكل قيمة في حالة عدم وجود المستخدم

def perform_operation(x, y):
    # دالة تقوم بعمليتين وترجع نتيجتيهما
    sum_result = x + y
    product_result = x * y
    return sum_result, product_result # ترجع المجموع والضرب كـ tuple

# استدعاء دالة ترجع قيم متعددة
name, age, profession = get_user_info(1)
print(f"المستخدم: {name}, العمر: {age}, الوظيفة: {profession}")

# استدعاء دالة ترجع قيم متعددة وتفكيكها مباشرة
total, prod = perform_operation(10, 5)
print(f"المجموع: {total}, حاصل الضرب: {prod}")

في هذا الجزء، رأينا كيف يمكن لدالة get_user_info أن ترجع معلومات كاملة عن المستخدم في عملية واحدة، وكيف يمكن لـ perform_operation أن ترجع نتائج عمليات مختلفة.

الكود النهائي الكامل

إليك الكود كاملاً الذي يجمع كل المفاهيم التي تناولناها:

# دالة ترحيب بسيطة تستقبل اسماً
def greet_user(name):
    return f"أهلاً بك يا {name}!"

# دالة لحساب المساحة بمعامل افتراضي للعرض
def calculate_area(length, width=10):
    return length * width

# دالة لمعالجة البيانات تستقبل معرف، ثم عدد غير محدد من المعاملات الموضعية ومعاملات المفاتيح
def process_data(data_id, *args, **kwargs):
    print(f"\n--- معالجة بيانات رقم {data_id} ---")
    print(f"البيانات الإضافية (موضعية): {args}")
    print(f"الخيارات الإضافية (مفاتيح): {kwargs}")
    print("---------------------------------")

# دالة تحاكي جلب بيانات المستخدم وترجع قيم متعددة
def get_user_info(user_id):
    if user_id == 1:
        return "علي", 30, "مطور برمجيات"
    elif user_id == 2:
        return "فاطمة", 25, "مصممة واجهات"
    else:
        return None, None, None

# دالة تقوم بعمليتين وترجع نتيجتيهما
def perform_operation(x, y):
    sum_result = x + y
    product_result = x * y
    return sum_result, product_result

# --- أمثلة على الاستخدام ---

# 1. استخدام دالة الترحيب
print(greet_user("سارة"))

# 2. استخدام دالة حساب المساحة
area_default = calculate_area(8) # استخدام العرض الافتراضي
print(f"مساحة المستطيل (طول 8، عرض افتراضي): {area_default}")

area_custom = calculate_area(length=6, width=4) # تحديد الطول والعرض بالمفاتيح
print(f"مساحة المستطيل (طول 6، عرض 4): {area_custom}")

# 3. استخدام دالة معالجة البيانات
process_data(200, "تقرير", "بيانات_شهرية", حالة="مكتمل", تاريخ="2023-10-26")
process_data(300, "تحليل", "نتائج_أولية", مرحلة="قيد_المراجعة")

# 4. استخدام دالة جلب معلومات المستخدم
user1_name, user1_age, user1_job = get_user_info(1)
print(f"\nمعلومات المستخدم 1: الاسم: {user1_name}, العمر: {user1_age}, الوظيفة: {user1_job}")

user3_name, user3_age, user3_job = get_user_info(3) # مستخدم غير موجود
print(f"معلومات المستخدم 3: الاسم: {user3_name}, العمر: {user3_age}, الوظيفة: {user3_job}")

# 5. استخدام دالة العمليات الحسابية
total_val, product_val = perform_operation(20, 5)
print(f"\nللقيمتين 20 و 5: المجموع هو {total_val}، وحاصل الضرب هو {product_val}")

النتيجة المتوقعة

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

أهلاً بك يا سارة!
مساحة المستطيل (طول 8، عرض افتراضي): 80
مساحة المستطيل (طول 6، عرض 4): 24

--- معالجة بيانات رقم 200 ---
البيانات الإضافية (موضعية): ('تقرير', 'بيانات_شهرية')
الخيارات الإضافية (مفاتيح): {'حالة': 'مكتمل', 'تاريخ': '2023-10-26'}
---------------------------------

--- معالجة بيانات رقم 300 ---
البيانات الإضافية (موضعية): ('تحليل', 'نتائج_أولية')
الخيارات الإضافية (مفاتيح): {'مرحلة': 'قيد_المراجعة'}
---------------------------------

معلومات المستخدم 1: الاسم: علي, العمر: 30, الوظيفة: مطور برمجيات
معلومات المستخدم 3: الاسم: None, العمر: None, الوظيفة: None

للقيمتين 20 و 5: المجموع هو 25، وحاصل الضرب هو 100