القيم المرجعة return في بايثون

حتى الآن، تعلمنا كيف ننشئ دوالاً تستقبل بيانات وتنفذ عمليات. لكن الدوال الحقيقية في البرمجة الاحترافية لا تكتفي بالطباعة، بل تُرجع نتائج يمكن استخدامها في أماكن أخرى من البرنامج. هذا ما تفعله جملة return.

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

في هذا الدرس، ستتعلم كل ما يتعلق بجملة return: كيف تعمل، متى تستخدمها، وكيف ترجع قيماً متعددة من دالة واحدة.

1. الفرق بين print و return

هذا من أكثر المفاهيم التي تُربك المبتدئين. دعنا نوضح الفرق بشكل قاطع.

الخاصية print() return
الوظيفة عرض قيمة على الشاشة إرجاع قيمة للاستخدام
القيمة الناتجة None القيمة المحددة
إيقاف الدالة لا نعم، فوراً
الاستخدام في تعبيرات لا يمكن نعم، يمكن
print_vs_return.py
# دالة تستخدم print (للعرض فقط)
def add_print(a, b):
    result = a + b
    print(f"النتيجة: {result}")

# دالة تستخدم return (للإرجاع)
def add_return(a, b):
    result = a + b
    return result

# الفرق في الاستخدام:
print("=== استخدام print ===")
x = add_print(5, 3)
print(f"القيمة المخزنة: {x}")  # None!

print("\n=== استخدام return ===")
y = add_return(5, 3)
print(f"القيمة المخزنة: {y}")  # 8

# return يمكن استخدامه في تعبيرات
print(f"\nالضعف: {add_return(5, 3) * 2}")
print(f"مجموع عمليتين: {add_return(10, 5) + add_return(3, 2)}")
النتيجة
=== استخدام print === النتيجة: 8 القيمة المخزنة: None === استخدام return === القيمة المخزنة: 8 الضعف: 16 مجموع عمليتين: 20

2. صيغة return الأساسية

جملة return تُنهي تنفيذ الدالة فوراً وتُرجع القيمة المحددة. أي كود بعد return لن يُنفذ.

basic_return.py
# دالة بسيطة ترجع قيمة
def square(number):
    return number ** 2

# دالة ترجع نتيجة عملية مباشرة
def calculate_area(length, width):
    return length * width

# دالة مع معالجة قبل الإرجاع
def format_name(first, last):
    full_name = f"{first} {last}"
    formatted = full_name.strip().title()
    return formatted

# استخدام الدوال
print(f"مربع 5: {square(5)}")
print(f"مساحة 10x4: {calculate_area(10, 4)}")
print(f"الاسم: {format_name('  أحمد  ', '  محمد  ')}")
النتيجة
مربع 5: 25 مساحة 10x4: 40 الاسم: أحمد محمد

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

من أقوى ميزات بايثون إمكانية إرجاع عدة قيم من دالة واحدة. تُرجع القيم كـ tuple ويمكن فكها عند الاستقبال.

multiple_returns.py
# دالة ترجع قيمتين
def divide_with_remainder(a, b):
    quotient = a // b
    remainder = a % b
    return quotient, remainder

# دالة ترجع إحصائيات متعددة
def analyze_numbers(numbers):
    total = sum(numbers)
    count = len(numbers)
    average = total / count
    minimum = min(numbers)
    maximum = max(numbers)
    return total, count, average, minimum, maximum

# استخدام القيم المرجعة
q, r = divide_with_remainder(17, 5)
print(f"17 / 5 = {q} والباقي {r}")

# تحليل قائمة أرقام
grades = [85, 92, 78, 95, 88]
total, count, avg, min_g, max_g = analyze_numbers(grades)

print(f"\n--- تحليل الدرجات ---")
print(f"المجموع: {total}")
print(f"العدد: {count}")
print(f"المتوسط: {avg:.2f}")
print(f"الأدنى: {min_g}")
print(f"الأعلى: {max_g}")
النتيجة
17 / 5 = 3 والباقي 2 --- تحليل الدرجات --- المجموع: 438 العدد: 5 المتوسط: 87.60 الأدنى: 78 الأعلى: 95

4. الإرجاع المشروط

يمكن استخدام return في أماكن متعددة داخل الدالة للخروج المبكر بناءً على شروط معينة.

conditional_return.py
# دالة للتحقق من العمر
def check_age(age):
    if age < 0:
        return "عمر غير صالح"
    elif age < 13:
        return "طفل"
    elif age < 20:
        return "مراهق"
    elif age < 60:
        return "بالغ"
    else:
        return "كبير السن"

# دالة للتحقق من صحة البيانات
def validate_email(email):
    if not email:
        return False, "البريد فارغ"
    
    if "@" not in email:
        return False, "البريد يجب أن يحتوي على @"
    
    if "." not in email.split("@")[1]:
        return False, "النطاق غير صالح"
    
    return True, "البريد صالح"

# اختبار الدوال
ages = [5, 15, 25, 70, -5]
for age in ages:
    print(f"العمر {age}: {check_age(age)}")

print()

emails = ["test@email.com", "invalid", "", "test@domain"]
for email in emails:
    valid, message = validate_email(email)
    status = "صالح" if valid else "غير صالح"
    print(f"{email or '(فارغ)'}: {status} - {message}")

5. return None والدوال بدون return

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

return_none.py
# دالة بدون return (ترجع None)
def say_hello(name):
    print(f"مرحباً يا {name}")

# دالة مع return فارغ
def process_data(data):
    if not data:
        return  # يرجع None ويخرج
    
    print(f"معالجة: {data}")

# دالة مع return None صريح
def find_user(user_id):
    users = {1: "أحمد", 2: "سارة"}
    
    if user_id in users:
        return users[user_id]
    
    return None  # صريح وواضح

# اختبار
result1 = say_hello("أحمد")
print(f"القيمة المرجعة: {result1}")

print()
result2 = find_user(1)
result3 = find_user(99)
print(f"البحث عن 1: {result2}")
print(f"البحث عن 99: {result3}")
النتيجة
مرحباً يا أحمد القيمة المرجعة: None البحث عن 1: أحمد البحث عن 99: None

6. إرجاع أنواع بيانات مختلفة

يمكن للدالة إرجاع أي نوع من البيانات: أرقام، نصوص، قوائم، قواميس، أو حتى دوال أخرى.

return_types.py
# إرجاع قائمة
def get_even_numbers(limit):
    return [i for i in range(limit) if i % 2 == 0]

# إرجاع قاموس
def create_user(name, age, city):
    return {
        "name": name,
        "age": age,
        "city": city,
        "active": True
    }

# إرجاع قيمة منطقية
def is_adult(age):
    return age >= 18

# استخدام الدوال
evens = get_even_numbers(10)
print(f"الأرقام الزوجية: {evens}")

user = create_user("أحمد", 25, "القاهرة")
print(f"\nالمستخدم: {user}")

print(f"\nهل 20 بالغ؟ {is_adult(20)}")
print(f"هل 15 بالغ؟ {is_adult(15)}")
النتيجة
الأرقام الزوجية: [0, 2, 4, 6, 8] المستخدم: {'name': 'أحمد', 'age': 25, 'city': 'القاهرة', 'active': True} هل 20 بالغ؟ True هل 15 بالغ؟ False

7. تطبيق عملي: حاسبة متقدمة

calculator.py
def calculate(a, b, operation):
    """حاسبة بسيطة مع معالجة الأخطاء"""
    
    if operation == "+":
        return a + b, None
    elif operation == "-":
        return a - b, None
    elif operation == "*":
        return a * b, None
    elif operation == "/":
        if b == 0:
            return None, "لا يمكن القسمة على صفر"
        return a / b, None
    elif operation == "**":
        return a ** b, None
    else:
        return None, f"عملية غير معروفة: {operation}"

# اختبار الحاسبة
operations = [
    (10, 5, "+"),
    (10, 5, "-"),
    (10, 5, "*"),
    (10, 5, "/"),
    (10, 0, "/"),
    (2, 8, "**"),
    (10, 5, "%"),
]

print("نتائج العمليات الحسابية:")
print("-" * 40)

for a, b, op in operations:
    result, error = calculate(a, b, op)
    
    if error:
        print(f"{a} {op} {b} = خطأ: {error}")
    else:
        print(f"{a} {op} {b} = {result}")

8. أفضل الممارسات

افعل
  • استخدم return بدلاً من print للنتائج
  • أرجع None صراحة عند الحاجة
  • استخدم الإرجاع المبكر للتحقق من الأخطاء
  • وثق نوع القيمة المرجعة في docstring
لا تفعل
  • لا تخلط بين print و return
  • لا تتجاهل القيم المرجعة
  • لا تُرجع أنواعاً مختلفة بشكل عشوائي
  • لا تضع كود بعد return (لن يُنفذ)
ملخص الدرس
  • return ترجع قيمة من الدالة للاستخدام لاحقاً
  • تختلف عن print التي تعرض فقط
  • يمكن إرجاع قيم متعددة كـ tuple
  • الدالة بدون return ترجع None
  • return ينهي تنفيذ الدالة فوراً

الخطوة التالية

تعلم القوائم (Lists) - أحد أهم هياكل البيانات في بايثون

الدرس التالي: القوائم (Lists)
المحرر الذكي

اكتب الكود وشاهد النتيجة فوراً

جرب الآن مجاناً
قناة ديف عربي

تابع أحدث الدروس والتحديثات مباشرة على واتساب

انضم الآن