--------------------------------------------------------------------------- IndexError Traceback (most recent call last) Cell In[1], line 3 1 my_list = [10, 20, 30] 2 idx = 3 ----> 3 value = my_list[idx] IndexError: list index out of range
12 الاستثناء
الاستثناء (Exception) هو خروج البرنامج عن المسار المثالي. ويسمى أيضًا الخطأ العملي (Runtime Error). مثل:
- أن يؤمَر بقراءة ملف .. والواقع أن هذا الملف غير موجود!
- أو أن يطلب من المستخدم رقمًا فيعطيه كلاماً!
- أو أن يطلب من الشبكة شيئًا .. فتنقطع الشبكة!
فكل هذه تعتبر مسارات غير مثالية لكنها تحصل في ظروف واقعيَّة. فيجب كتابة قطع في البرنامج تتعامل معها. ولذا فإن بعض الممارسين لا يفضلون استعمال كلمة استثناء لأنَّ مثل ذلك يحصل كثيرًا فهو ليس خارجًا عن العادة؛ بل من الطبيعي أن يحصل ذلك في الواقع!
تغير سير الأوامر عند الخطأ
تنفذ التعليمات في لغة البرمجة الأمرية (Imperative) كبايثون بحسب ترتيبها (من الأعلى إلى الأسفل). لكن عند حدوث خطأ، يتغيَّر سيْر الأوامر باستعمال جملة try-except
. وشكل جملة التعامل مع الخطأ على هذا النحو:
- المحاولة:
try
تتضمن الجملة التي نتوقع حدوث خطأٍ فيها - المطابقة:
except Exception
هي مثلif
تنفذ ما تتضمنه إن كان الخطأ من نوعExcpetion
- عدم المطابقة:
else
تعمل عند عدم الخطأ - المتابعة:
finally
وهي جُملة تعمل سواء وقع الخطأ أم لم يقع؛ لكنَّ بايثون تضمن عملها إن حصل خطأ أثناء التعامل مع الخطأ
أنواع الاستثناء
تم تعريف أنواع من الخطأ في بايثون متبوعة بكلمة Error
، وذلك باعتبار حالات خطأ نمطية ومتكررة:
SyntaxError
السبب: خطأ نحوي في صياغة اللغة:
- كلمة غير صحيحة: خطأ في الإملاء
- في وضع كلمة صحيحة في غير سياقها
- محاذاة غير متسقة (
IndentationError
)
الحل: اقرأ رسالة الخطأ وستدلُّك على السبب والموضع الذي حصل فيه الخطأ.
TypeError
السبب:
- طلب فعل بعدد أكثر أو أقل من العوامل الواجبة (مثل:
len(1, 2)
) - طلب فعل بعوامل لا تطابق النوع المحدد في تعريفه (مثل:
math.sqrt('nine')
أو5 + '5'
)
الحل: الوقاية بـ type()
أو isinstance()
أو بالتأكد من تحويل النوع مسبقًا.
ValueError
السبب: أن يكون النوع صحيحًا (فلا يحصُل TypeError
) لكن القيمة غير مقبولة.
- مثلاً: طلب فعل بقيمة نوعها عددي لكنَّها سالبة وهو لا يقبل إلا الموجبة. نحو:
math.sqrt(-16)
فالجذر التربيعي لا يقبل السالب.
الحل: الوقاية بفحص مدى القيمة ، نحو: if x >=0: math.sqrt(x)
IndexError
& KeyError
السبب: الرقم الذي استعمل في عملية الإشارة [index]list
(قائمة) أو dict[key]
(قاموس) يشير لما هو خارج المجموعة.
نحو:
الحل بالوقاية:
أو بالعلاج:
وكذلك في القاموس، نحو:
--------------------------------------------------------------------------- KeyError Traceback (most recent call last) Cell In[2], line 3 1 my_dict = {'A': 10, 'B': 20, 'C': 30} 2 key = 'Z' ----> 3 value = my_dict[key] KeyError: 'Z'
الحل بالوقاية
أو هكذا (تعيين قيمة ابتدائية):
أو بالعلاج:
AttributeError
& NameError
السبب: استعمال متغير أو فعل قبل تعريفه.
- فإن أسنِد إلى كائن؛ وقع
AttributeError
- وإلا وقع
NameError
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[3], line 2 1 a = 10 ----> 2 a + X NameError: name 'X' is not defined
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[4], line 1 ----> 1 some_function(55) NameError: name 'some_function' is not defined
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[5], line 5 2 pass 4 a = A() ----> 5 a.x AttributeError: 'A' object has no attribute 'x'
ModuleNotFoundError
السبب: فشل جُملة الاستيراد import numpy
الحل:
- تأكد من صحة الإملاء
- تأكد من تثبيت الوحدة في البيئة التي يعمل فيها البرنامج:
pip install numpy
تعريف أخطاء جديدة
تعريف الخطأ يكون بتعريف نوع جديد يرث من النوع Exception
، وهذا ما يحققه السطر الأول بين القوسين. وتستطيع أن ترث ممن يرث، فتتكون لديك فروع من هذا الخطأ:
flowchart TD A[ParentError] --> B[XError] A --> C[YError]
وهذا الإجراء يحصل فيه الخطأ بطريقة مصطنعة لكنها توضح ما نريد، وهو الخطأ الفرعي XError
الذي يرث من الخطأ الأصلي ParentError
:
ثم حين نفحص، تسطيع أن نطابق بالأصل أو الفرع:
المصطلحات
العربية | الإنجليزية |
---|---|
الاستثناء | Exception |
خطأ | Error |
ظرف التنفيذ | Execution Frame |
الوقاية | If-else |
العلاج | Try-except |
خطأ نحوي | Syntax Error |
خطأ في المحاذاة | Indentation Error |
خطأ في النوع | Type Error |
خطأ في القيمة | Value Error |
خطأ في المؤشر الرقمي | Index Error |
خطأ في المؤشر المرقوم | Key Error |
خطأ في الخاصية | Attribute Error |
خطأ في الاسم | Name Error |
خطأ في استيراد الوحدة | Module Not Found Error |
خطأ القسمة على صفر | Zero Division Error |
رفع الخطأ | Raise Exception |
إلتقاط الخطأ | Catch Exception |
تدفق الخطأ | Error Flow |