بايثون / برامج موثوقة / الدرس 8
الأخطاء والاستثناءات وتصحيح البرامج
حوّل الفشل إلى معلومات دقيقة مع حفظ أسبابه، ثم افحص أصغر حالة تعيد إنتاجه.
في هذه الصفحة
أهداف الدرس
- قراءة التتبع بوصفه دليلا
- سياق مفيد دون كشف البيانات
قراءة التتبع بوصفه دليلا
يمنع الخطأ النحوي تحليل المصدر، بينما يوقف الاستثناء التنفيذ أثناء العمل. يعرض التتبع سلسلة الاستدعاءات ونوع الاستثناء ورسالته. ابدأ من العملية الأخيرة ثم اصعد لمعرفة المستدعي الذي قدم الحالة المشكلة. السطر الأخير بداية التشخيص لا نهايته؛ فقد تكشف عملية حساب فاشلة تحويلا غير صحيح سابقا. احفظ الرسالة الدقيقة والمدخل المصغر وإصدار المفسر في التقرير. إعادة إنتاج الفشل نفسه أنفع من تغيير عدة أسطر غير مترابطة أملا في اختفائه.
التقاط ما تستطيع معالجته
يجب أن تحيط try بأصغر عملية تستطيع معالجة فشلها المتوقع. التقط أنواعا محددة، ثم تعاف وفق قاعدة موثقة أو أضف سياقا وأعد الرفع. قد يخفي except Exception عيوبا برمجية إذا استبدلها بنتيجة طبيعية. تنفذ else عند نجاح try، وتناسب finally التنظيف الذي لا يغطيه مدير سياق. تجنب return من finally لأنها قد تخفي استثناء أو تستبدل نتيجة معلقة. يجب أن يبقى الفشل غير المتوقع ظاهرا عند حد يستطيع الإبلاغ عنه بمسؤولية.
تحويل الأخطاء مع حفظ السبب
لا تستخدم أخطاء التحويل الدنيا دائما مفردات يفهمها المستدعي. يمكن لاستثناء مجال توضيح الحقل الفاشل مع ربط الأصل باستخدام raise ... from error. يحفظ الربط دليلا للتصحيح. يحلل المثال الكمية داخل try ضيقة ثم يتحقق من المجال خارجها، فتختلف رسالة النص غير الصالح عن العدد السالب. يلتقط العرض خطأ المجال المتوقع لطباعة نتيجة ثابتة؛ أما التطبيق فيقرر عند حده الخارجي طلب التصحيح أو رفض الطلب أو الإنهاء.
class QuantityError(ValueError):
pass
def parse_quantity(text):
try:
quantity = int(text)
except ValueError as error:
raise QuantityError("quantity must be an integer") from error
if quantity < 0:
raise QuantityError("quantity must be nonnegative")
return quantity
try:
parse_quantity("many")
except QuantityError as error:
print(error)
print(type(error.__cause__).__name__)
quantity must be an integer
ValueError
يضيف خطأ المجال معنى الحقل وتحتفظ __cause__ بخطأ التحويل الأصلي. يثبت اسم الفئة الربط دون أسطر تتبع تختلف بحسب الجهاز.
فحص الافتراضات خطوة بخطوة
يتيح المصحح إيقاف التنفيذ لفحص المتغيرات والتقدم بين التعليمات. تدخل breakpoint المصحح المضبوط، وتتوفر pdb في المكتبة القياسية. استخدمها في عملية محلية مضبوطة لأن إيقاف عامل إنتاج يؤثر في توفره. ابدأ بفرضية، مثل استبدال المجموع في الدورة الثانية، وافحص المتغير في النقطة المعنية بدلا من المرور على كل وحدة مستوردة. يستخدم المثال الثاني جدولا مطبوعا لتتبع الحلقة، فيقدم الانضباط نفسه دون أسئلة تفاعلية.
total = 0
for position, value in enumerate([2, 5], start=1):
before = total
total += value
print(position, before, value, total)
1 0 2 2
2 2 5 7
يسجل كل صف الموقع والمجموع القديم والمدخل والمجموع الجديد، فيظهر أي تصفير خاطئ عند أول دورة مختلفة.
سياق مفيد دون كشف البيانات
يسجل السجل أحداثا للفحص اللاحق ويختلف عن إرجاع نتائج التطبيق. اختر المستوى بحسب المعنى التشغيلي، وأضف معرفات تربط الأحداث، وتجنب الأسرار والحمولات الحساسة كاملة. تسجل logging.exception داخل المعالج معلومات التتبع. لا تكرر الخطأ نفسه في كل طبقة فتنتج ضوضاء. ضيق المدخل وحدد الثابت المتوقع ولاحظ الحالة الفعلية، ثم غير سببا واحدا وأعد التجربة. بعد الإصلاح احفظ اختبار منع تراجع يصف السلوك الخارجي، لا كل طباعات التصحيح المؤقتة.
الأخطاء الشائعة وإصلاحها
تحول ملف غير صالح إلى تقرير فارغ بصمت
- لماذا يحدث؟
- يعيد معالج واسع بيانات فارغة لأي استثناء.
- كيف تصلحه؟
- التقط الفشل المتوقع بدقة وأبلغ عن غير القابل للتعافي.
- كيف تتجنب تكراره؟
- اختبر المدخل التالف منفصلا عن الفارغ الحقيقي.
اختفاء الفشل الأصلي من التشخيص
- لماذا يحدث؟
- أسقط تحويل الخطأ علاقة السبب.
- كيف تصلحه؟
- استخدم ربط الاستثناءات عند تغيير مستوى التجريد.
- كيف تتجنب تكراره؟
- افحص رسالة المجال والسبب في اختبارات محددة.
كشف التصحيح بيانات اعتماد في السجل
- لماذا يحدث؟
- سجلت كائنات المدخلات كاملة دون مراجعة محتواها.
- كيف تصلحه؟
- سجل الحقول الآمنة الضرورية واحجب القيم الحساسة.
- كيف تتجنب تكراره؟
- صمم حقول السجل بعناية مماثلة لرسائل الخطأ العامة.
اختبر فهمك
1. كيف يميز محلل عدد بين الصيغة غير الصالحة والقيمة السالبة الممنوعة؟
اعرض الحل المشروح
ضع int(text) وحدها داخل try تلتقط ValueError وتحوله برسالة صيغة مع حفظ السبب. افحص quantity < 0 بعد التحويل وارفع خطأ مجال خاصا بالنطاق. يمنع فصل التحقق التقاط خطأ مقصود بوصفه فشل تحويل.
2. ضع خطة تصحيح لمجموع يخطئ في الدورة الثانية فقط.
اعرض الحل المشروح
استخدم أصغر مدخل من عنصرين يعيد الفشل. سجل المجموع القديم والقيمة والمجموع الجديد في كل دورة، وقارن بثابت مجموع البادئة. أصلح أول موضع اختلاف وأضف اختبارا لعنصرين مع حالتي الفراغ والعنصر الواحد.
أهم ما تعلمته
- التقط الاستثناء حيث توجد استجابة ذات معنى.
- احفظ الأسباب عند تحويل الأخطاء.
- أعد الإنتاج وافحص وأصلح واحفظ حالة تمنع التراجع.