🛡️ Try Except في بايثون: درع حماية برامجك من الأخطاء!

مرحباً بك في درس جديد ومهم جداً! تخيل أنك تقود سيارة، وفجأة ظهرت إشارة تحذير على الشاشة تخبرك بأن درجة حرارة المحرك مرتفعة. ماذا ستفعل؟ ستتوقف فوراً لفحص المشكلة قبل أن تتفاقم وتتسبب في تلف السيارة، أليس كذلك؟ 🚗

في عالم البرمجة، تحدث أخطاء غير متوقعة طوال الوقت، تماماً مثل تلك الإشارة التحذيرية. try و except في لغة بايثون هما الأداتان السحريتان اللتان تمنحان برنامجك "الذكاء" للتعامل مع هذه الأخطاء بذكاء، بدلاً من التوقف عن العمل فجأة وإظهار رسائل مخيفة للمستخدم. هيا نتعلم كيف نستخدمهما! 🧙‍♂️


🤔 لماذا نحتاج إلى try و except؟

لنبدأ بمثال بسيط. تخيل أنك كتبت برنامجاً يطلب من المستخدم إدخال رقمين ثم يقوم بقسمة الأول على الثاني.

# مثال بدون try except (خطير!)
num1 = int(input("أدخل الرقم الأول: "))
num2 = int(input("أدخل الرقم الثاني: "))

result = num1 / num2
print(f"نتيجة القسمة هي: {result}")

ماذا يحدث إذا أدخل المستخدم الرقم صفر كقيمة للرقم الثاني؟ 🤯 سيحاول البرنامج تنفيذ num1 / 0، وهي عملية رياضية غير مسموح بها (القسمة على صفر). ستتوقف البرنامج فوراً ويظهر خطأ يسمى ZeroDivisionError.

الأسوأ من ذلك، ماذا لو أدخل المستخدم كلمة مثل "مرحباً" بدلاً من رقم؟ سيفشل تحويل النص إلى عدد صحيح (int()) وسيتوقف البرنامج بخطأ ValueError.

هنا يأتي دور try و except لإنقاذ الموقف! فهما يسمحان لبرنامجك بمحاولة تنفيذ كود قد يسبب خطأ، وإذا حدث خطأ، فإنه يستثني هذا الخطأ ويتعامل معه بطريقة أنيقة دون توقف البرنامج.


🧱 البنية الأساسية لـ try و except

هيكل try و except بسيط جداً ويتكون من جزأين رئيسيين:

try:
    # الكود الذي تريد "محاولة" تنفيذه
    # قد يسبب هذا الكود خطأً (Exception)
    # ضع هنا الأوامر الحساسة مثل فتح ملف، أو القسمة، أو تحويل المدخلات.
    risky_operation = 10 / 2
    print("المحاولة ناجحة!")
except:
    # الكود الذي ينفذ "فقط في حالة" حدوث خطأ في كتلة try
    # هنا تتعامل مع الخطأ بطريقة ودية
    print("حدث خطأ ما أثناء التنفيذ!")

كيف يعمل؟

  1. يدخل البرنامج إلى كتلة try ويبدأ في تنفيذ الأوامر بداخلها سطراً سطراً.
  2. إذا تم تنفيذ جميع أوامر try بنجاح، يتم تخطي كتلة except بالكامل والمتابعة إلى ما بعدها.
  3. إذا حدث أي خطأ أثناء تنفيذ كتلة try، يتوقف التنفيذ فيها فوراً وينتقل البرنامج إلى كتلة except لتنفيذ الأوامر الموجودة فيها.

لنجرب المثال السابق بعد تحسينه:

try:
    num1 = int(input("أدخل الرقم الأول: "))
    num2 = int(input("أدخل الرقم الثاني: "))
    result = num1 / num2
    print(f"نتيجة القسمة هي: {result}")
except:
    print("عفواً! حدث خطأ. يرجى التأكد من إدخال أرقام صحيحة وأن الرقم الثاني لا يساوي الصفر.")

الآن، بغض النظر عما يفعله المستخدم (قسمة على صفر، إدخال نص، إلخ)، سيطبع البرنامج رسالة الودية التي كتبناها ويستمر في العمل بسلاسة! ✨


🎯 التقاط أخطاء محددة مع except

استخدام except بمفرده يلتقط جميع أنواع الأخطاء. لكن الأفضل هو أن تكون أكثر دقة! يمكنك تحديد نوع الخطأ الذي تريد التعامل معه.

try:
    num = int(input("أدخل رقمًا: "))
    result = 10 / num
    print(f"10 ÷ {num} = {result}")

except ZeroDivisionError:
    # هذا الكود ينفذ فقط إذا كان الخطأ من نوع "القسمة على صفر"
    print("لا يمكنك القسمة على الصفر!")

except ValueError:
    # هذا الكود ينفذ فقط إذا كان الخطأ من نوع "قيمة غير صحيحة" (مثل إدخال نص)
    print("يجب إدخال رقم صحيح فقط!")

مميزات هذه الطريقة:

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

📝 مثال شامل: برنامج آلة حاسبة صغيرة

لنطبق ما تعلمناه في مثال عملي بسيط:

print("مرحباً بك في الآلة الحاسبة الآمنة!")
print("سأقوم بقسمة الرقم 100 على الرقم الذي تدخله.")

try:
    # المحاولة
    user_input = input("أدخل رقمك: ")
    number = float(user_input)  # استخدمنا float لقبول الأرقام العشرية أيضاً
    answer = 100 / number

    # إذا وصلنا إلى هنا، فالمحاولة ناجحة
    print(f("100 ÷ {number} = {answer:.2f}"))  # :.2f لعرض نتيجتين عشريتين فقط

except ZeroDivisionError:
    print("❌ تنبيه! القسمة على الصفر غير ممكنة في الرياضيات.")

except ValueError:
    print(f("❌ '{user_input}' ليس رقماً صحيحاً. يرجى إدخال رقم."))

print("شكراً لك على استخدام البرنامج! 👋")

بهذا الشكل، أصبح برنامجنا:

  1. مرن: يتعامل مع مدخلات المستخدم المختلفة.
  2. مستقر: لا يتوقف فجأة.
  3. ودود: يخبر المستخدم بطريقة لطيفة ما الخطأ الذي ارتكبه.

🧠 ملخص الدرس

  • try: تستخدم لتضمين الكود الذي قد يسبب خطأ أثناء التنفيذ. "جرب تنفيذ هذا الكود".
  • except: تستخدم لالتقاط الخطأ والتعامل معه إذا حدث داخل كتلة try. "استثني هذا الخطأ وافعل الآتي بدلاً من التوقف".
  • استخدام try/except يجعل برامجك أكثر قوة واستقراراً في وجه الأخطاء المتوقعة.
  • يمكنك استخدام except عامة لالتقاط جميع الأخطاء، أو محددة (مثل except ValueError) للتعامل مع أخطاء معينة بشكل دقيق.