2.4تدبير الأخطاء والاستثناءات
الأساسي في 30 ثانية
- أطر المحفوف بدقة : try على التحويل والملف والشبكة — لا كل البرنامج أبدا.
- التقط بدقة لا باتساع : except ValueError/FileNotFoundError مستهدَف — except العاري أو pass يدفن الأخطاء.
- أبلغ مبكرا وبقوة : raise لثوابتك، وelse/finally في محلهما، سجل ثم تدهور بنظافة.
حالة مستمرة — نبيل يجعل استيراد الشهر موثوقا
الفصل الأخير : استيراد نبيل الشهري يتعطل عند أول طارئ — تصدير غائب، ومبلغ غير رقمي، ومجموع مقسوم على صفر عندما لا عملية بيع. المستخدمون يرون أثرا أحمر. جعله موثوقا : تحويل المبالغ في try/except ValueError مع إعادة الطلب، والفتح في try/except FileNotFoundError برسالة واضحة، والقسمة محمية ضد ZeroDivisionError، والمبالغ السالبة مرفوضة بـ raise منذ إنشاء عملية Vente (2.3). والباقي يصعد بأثره : لا شيء مُسكَت. استيراد المستوى 2 مُسلَّم : بيانات ونص وكائنات وأخطاء مُدبَّرة.
خاتمة الخيط الرابط 2.1-2.3 : استيراد نبيل لا يتعطل بعد اليوم عند أول طارئ.
1. الاستثناء ليس كارثة
ValueError وKeyError وFileNotFoundError وZeroDivisionError : كائنات إعلامية لا إهانات. try/except يؤطر المحفوف بدقة (تحويل مدخل، فتح ملف، قسمة) — لا كل البرنامج أبدا : الالتقاط الواسع يخفي الأخطاء. التتبع (Traceback) يُقرَأ من الأسفل إلى الأعلى : نوع الخطأ ثم السطر المخطئ. نبيل يطبق ذلك : وحده تحويل المبالغ مؤطر، لا كل الاستيراد.
2. try/except/else/finally : لكل دوره
try تحوي المحفوف، وexcept ValueError تلتقط نوعا دقيقا برسالة مفيدة، وelse تنفذ التتمة إن سار كل شيء، وfinally تنظف دائما (تغلق وتحرر — حتى عند الخطأ). raise ValueError("...") تُبلغ عن ثوابتك : المبلغ السالب مرفوض مبكرا وبقوة منذ الإنشاء. نبيل يرفض هكذا المبالغ السالبة في __init__ : يُبلَّغ عن الخطأ عند المصدر، لا بعد ثلاث دوال.
3. اترك يمر ما لا تعالج
القاعدة الذهبية : لا نلتقط إلا ما نعرف علاجه (إعادة الطلب، قيمة افتراضية، رسالة واضحة). والباقي يصعد بأثره : إسكاته بـ except: pass يدفن أخطاء حية — أسوأ منعكس. except العاري يخفي كل شيء، بما فيه ما يجب أن تراه. في الإنتاج، نسجل ثم نتدهور بنظافة (رسالة للمستخدم وتوقف مضبوط). استيراد نبيل يعيد طلب المبالغ غير الصالحة، ويُبلغ عن التصدير الغائب — ويترك غير المتوقع يصعد.
هل تعلم ؟
خطأ مُسكَت يعمل ضدك بصمت.
🔎 مثال ملموس — 🔎 مثال ملموس — إدخال نبيل المتين دون إسكات
الدقيق مُلتقط، والباقي كان سيصعد، كما عند نبيل :
def lire_montant(texte):
try:
montant = float(texte)
except ValueError:
raise ValueError(f"مبلغ غير صالح : {texte!r}") from None
if montant < 0:
raise ValueError("المبلغ السالب ممنوع")
return montant
try:
print(lire_montant("1250.5"))
except ValueError as e:
print(f"خطأ : {e}")
القراءة : ValueError مستهدَف، والثابت مُبلَّغ بـ raise، ورسالة مفيدة.
الدرس : لا except: pass أبدا — فهي تدفن الأخطاء الحية.
مفردات القسم
- الاستثناء (Exception)
- خطأ يقع عند التنفيذ (ZeroDivisionError وValueError وFileNotFoundError…) يوقف البرنامج إن لم يُدبَّر. يُقرَأ من الأسفل إلى الأعلى في التتبع.
مثال بسيط: تصدير نبيل الغائب يرفع FileNotFoundError.
ما ليس كذلك: خطأ صياغة يمنع الانطلاق.
رد فعل: تعطل عند التنفيذ = استثناء يُقرَأ.
- try / except
- try تحوي الكود المحفوف (مقطع ضيق) ؛ وexcept تلتقط نوعا دقيقا وتنفذ علاجا حقيقيا بدل التعطل.
مثال بسيط: نبيل يحيط float(montant) بـ except ValueError.
ما ليس كذلك: except عارٍ يلتقط كل شيء دون علاج.
رد فعل: محفوف دقيق = try + except مستهدَف.
- else / finally
- else : التتمة إن لم يقع خطأ ؛ وfinally : تُنفَّذ في كل الحالات، مثالية لتحرير مورد (إغلاق ملف).
مثال بسيط: نبيل يعرض « اكتمل الاستيراد » في finally.
ما ليس كذلك: تنظيف لا يدور إلا عند النجاح.
رد فعل: تنظيف مضمون = finally.
- raise
- ترفع طوعا استثناء للإبلاغ عن وضع شاذ (ثابت مُنتَهَك) : الفشل مبكرا وبقوة، عند المصدر.
مثال بسيط: عملية Vente لنبيل ترفض المبالغ السالبة بـ raise.
ما ليس كذلك: عودة صامتة تترك بيانات خاطئة تمر.
رد فعل: ثابت مُنتَهَك = raise فوري.
- التتبع (Traceback)
- أثر الخطأ الذي تعرضه بايثون : يُقرَأ من الأسفل إلى الأعلى، ويشير إلى نوع الخطأ والسطر المخطئ. يُسجَّل ولا يُخفَى.
مثال بسيط: نبيل يقرأ أسفل التتبع ليجد التحويل المخطئ.
ما ليس كذلك: رسالة مخفية بـ except: pass.
رد فعل: التتبع = اقرأ الأسفل وصحح السطر.
في التطبيق — تطبيقيا — جعل برنامج موثوقا بـ try/except
- اطلب مبلغا وحوله : أحط float() بـ try/except ValueError يعيد الطلب عند مدخل غير رقمي.
- دبر متوسطا بالتقاط ZeroDivisionError (لا عملية بيع) برسالة واضحة بدل التعطل.
- افتح التصدير بـ try/except FileNotFoundError ؛ وأضف finally تعرض « اكتمل الاستيراد » في كل الحالات.
- اكتب دالة ترفع (raise) ValueError لمبلغ سالب، واختبرها بـ try/except.
نص جاهز — تبرير الاستهداف في مراجعة الكود (30 ثانية)
« لاستيراد نبيل، كل try ضيقة : التحويل في ValueError، والتصدير في FileNotFoundError، وعلاج حقيقي وراءهما. والمبالغ السالبة تذهب في raise منذ الإنشاء. ولا except pass : ما لا نعرف علاجه يصعد ويُسجَّل — لا ندفن خطأ أبدا. »
يُقال مع عرض except عارٍ مستبدَل بـ except مستهدَفين.
قالب للنسخ — استيراد موثوق من البداية إلى النهاية
import json
from pathlib import Path
def lire_montant(texte):
montant = float(texte)
if montant < 0:
raise ValueError("المبلغ السالب ممنوع")
return montant
fichier = Path("ventes.json")
try:
lignes = json.loads(fichier.read_text(encoding="utf-8"))
except FileNotFoundError:
print("التصدير غير موجود : تحقق من ventes.json")
lignes = []
try:
montants = [lire_montant(str(l)) for l in lignes]
except ValueError as e:
print(f"سطر غير صالح تم تجاهله : {e}")
montants = []
else:
print(f"{len(montants)} مبالغ مقروءة")
finally:
print("اكتمل الاستيراد")
تصدير غائب
ملف الشهر غائب : FileNotFoundError تعرض رسالة واضحة بدل أثر أحمر.
متوسط دون عملية بيع
لا عملية بيع في الجزائر اليوم : ZeroDivisionError مُلتقط، و« لا متوسط » معروض.
مبلغ ممنوع
مبلغ سالب يطلق raise منذ عملية Vente : الفشل مبكرا والإبلاغ عند المصدر.
✓ ممارسات جيدة
- تأطير المحفوف بدقة بمقاطع try ضيقة.
- التقاط أنواع دقيقة بعلاج حقيقي (else/finally في محلهما).
- الرفع بـ raise للثوابت ؛ والتسجيل ثم التدهور بنظافة.
✗ أخطاء شائعة
- استعمال except: العاري أو except: pass (يخفي ويدفن الأخطاء).
- تأطير كل البرنامج في try واحدة.
- الإسكات بدل العلاج (المواصلة ببيانات خاطئة).
النقاط الأساسية
- try/except تلتقط الأخطاء بدل ترك البرنامج يتعطل — مقطع ضيق على المحفوف.
- استهدف نوع الخطأ (ValueError وFileNotFoundError…) بدل except فارغ.
- else = التتمة إن سار كل شيء ؛ وfinally تُنفَّذ دائما : مثالية لتحرير مورد.
- raise ترفع استثناء للإبلاغ عن وضع شاذ ؛ وSyntaxError لا تُدبَّر بـ try.
تحدي 48 ساعة — طبق غدا
اجعل سكربتا حقيقيا موثوقا (سكربت نبيل أو سكربتك) : try ضيقة + except مستهدَفة على كل نقطة هشة (تحويل وملف وقسمة)، وraise لثابت، وfinally حقيقية — واطرد كل except: pass.
- أستطيع شرح try/except/else/finally ودور كل منها.
- أعرف الالتقاط بدقة والرفع بـ raise لثوابتي.
- حذفت كل except عارٍ أو مُسكَت من كودي.
أسئلة شائعة
هل نلتقط كل الأخطاء بـ except عام ؟
لا : « except: » العاري يخفي كل شيء، بما فيه أخطاء يجب أن تراها. التقط استثناءات مستهدَفة (except ValueError) لتدبير ما تتوقعه فقط، واترك الباقي يصعد. وهي قاعدة ذهبية للموثوقية.
ما الفرق بين خطأ الصياغة والاستثناء ؟
خطأ الصياغة (SyntaxError) يمنع البرنامج من الانطلاق : الكود مكتوب خطأ. والاستثناء يقع عند تنفيذ كود صحيح وإلا (ملف غائب وقسمة على صفر). وحدها الاستثناءات تُدبَّر بـ try/except.
ماذا يجب تجنبه مطلقا في تدبير الأخطاء ؟