التعامل مع الأخطاء في Python: try و except
الأخطاء جزء طبيعي من البرمجة. المستخدم قد يكتب كلمة بدلاً من رقم، أو يقسم على صفر، أو يطلب ملفاً غير موجود. في كل هذه الحالات تتوقف Python وتعرض رسالة خطأ مخيفة. في هذا الدرس ستتعلم كيف تلتقط الأخطاء وتتعامل معها بهدوء، بحيث يكمل برنامجك عمله بدلاً من أن ينهار.
أشهر أنواع الأخطاء
Section titled “أشهر أنواع الأخطاء”عندما يحدث خطأ أثناء التشغيل، تسمّيه Python استثناءً (Exception). وهذه أشهر الأنواع التي ستقابلها:
| الخطأ | متى يحدث؟ | مثال |
|---|---|---|
ZeroDivisionError |
القسمة على صفر | 10 / 0 |
ValueError |
قيمة غير مناسبة | int("abc") |
TypeError |
نوع غير مناسب | "5" + 5 |
IndexError |
فهرس غير موجود | [1, 2][5] |
KeyError |
مفتاح غير موجود في القاموس | {"a": 1}["b"] |
NameError |
متغير غير معرّف | print(x) |
لا تخف من رسائل الخطأ! اقرأ آخر سطر فيها دائماً: فيه نوع الخطأ ووصفه، وهذا يدلك على المشكلة غالباً.
try و except
Section titled “try و except”الفكرة بسيطة: ضع الكود الذي قد يسبب خطأ داخل try، واكتب ما تريد فعله عند حدوث الخطأ داخل except:
def to_number(text): try: return int(text) except ValueError as e: print("خطأ:", e) return 0
print(to_number("42"))print(to_number("أربعة"))42خطأ: invalid literal for int() with base 10: 'أربعة'0- في الاستدعاء الأول نجح التحويل، فلم يُنفّذ
exceptأبداً. - في الثاني فشل التحويل، فقفزت Python مباشرة إلى
exceptبدلاً من أن يتوقف البرنامج. - الكتابة
as eتحفظ تفاصيل الخطأ في المتغيرeلتعرضها أو تسجلها.
تخيّل try مثل لاعب السيرك على الحبل، و except هي شبكة الأمان تحته: إذا سقط، لا ينتهي العرض، بل تلتقطه الشبكة ويكمل.
else و finally
Section titled “else و finally”يمكنك إضافة جزأين اختياريين:
else: يُنفّذ فقط إذا لم يحدث خطأ.finally: يُنفّذ دائماً، حدث خطأ أم لم يحدث.
def safe_divide(a, b): try: result = a / b except ZeroDivisionError: print("لا يمكن القسمة على صفر!") return None else: print("تمت القسمة بنجاح") return result finally: print("انتهت المحاولة")
print(safe_divide(10, 2))print(safe_divide(10, 0))تمت القسمة بنجاحانتهت المحاولة5.0لا يمكن القسمة على صفر!انتهت المحاولةNoneلاحظ أن رسالة finally ظهرت في الحالتين. يُستخدم finally عادة لأعمال «التنظيف» مثل إغلاق ملف، لأنها يجب أن تحدث مهما كانت النتيجة.
مثال عملي: إدخال رقم صحيح
Section titled “مثال عملي: إدخال رقم صحيح”من أشهر استخدامات try أن تطلب من المستخدم رقماً، وتعيد السؤال حتى يكتب رقماً صحيحاً:
while True: try: age = int(input("كم عمرك؟ ")) break except ValueError: print("من فضلك اكتب رقماً، مثل 14")
print(f"عمرك {age} سنة")كم عمرك؟ أربعة عشرمن فضلك اكتب رقماً، مثل 14كم عمرك؟ 14عمرك 14 سنةهنا اجتمعت while True و break من درس سابق مع try و except، لتصنع برنامجاً لا ينهار مهما كتب المستخدم.
إطلاق خطأ بنفسك: raise
Section titled “إطلاق خطأ بنفسك: raise”أحياناً تريد أنت أن تعلن عن خطأ، عندما تصل لدالتك قيمة غير منطقية:
def set_age(age): if age < 0: raise ValueError("العمر لا يمكن أن يكون سالباً") return age
try: set_age(-5)except ValueError as e: print("رسالة الخطأ:", e)رسالة الخطأ: العمر لا يمكن أن يكون سالباًجرّب بنفسك
Section titled “جرّب بنفسك”اكتب برنامج «آلة حاسبة آمنة» يطلب رقمين ويقسم الأول على الثاني، ويتعامل مع خطأين: كتابة شيء غير الرقم (ValueError)، والقسمة على صفر (ZeroDivisionError). يمكنك كتابة أكثر من except واحدة بعد try. مثال:
الرقم الأول: 10الرقم الثاني: 0لا يمكن القسمة على صفر!أخطاء شائعة
Section titled “أخطاء شائعة”- استخدام except فارغة: تخفي أخطاء حقيقية. حدّد نوع الخطأ.
- وضع كود كثير داخل try: يصعّب معرفة السطر الذي فشل.
- تجاهل الخطأ بصمت:
except ValueError: passبدون أي رسالة تجعل المستخدم لا يفهم ما حدث. اعرض رسالة مفيدة دائماً.
اختبر نفسك
Section titled “اختبر نفسك”سؤال
ما نوع الخطأ الذي يسببه int('abc')؟
النوع صحيح (نص) لكن قيمته لا يمكن تحويلها إلى رقم، فهو ValueError.
سؤال
متى يُنفّذ جزء finally؟
finally يُنفّذ دائماً، ولذلك يُستخدم لأعمال التنظيف مثل إغلاق الملفات.
الخلاصة
Section titled “الخلاصة”- الأخطاء أثناء التشغيل تسمى استثناءات، واقرأ آخر سطر في رسالة الخطأ لتفهمها.
- ضع الكود الذي قد يفشل في
try، والتعامل مع الخطأ فيexcept نوع_الخطأ:. elseتُنفّذ عند النجاح، وfinallyتُنفّذ دائماً.raiseتطلق خطأً بنفسك عند وصول قيمة غير منطقية.- حدّد نوع الخطأ دائماً، ولا تستخدم
exceptفارغة.