في لغة البرمجة بايثون ميزتان رئيسيتان للتعامل مع الأخطاء غير المتوقعة وهما:
- معالجة الاستثناءات.
- التأكيدات.
قائمة بالتأكيدات المعيارية
اسم الاستثناء | الوصف |
---|---|
Exception | الصف الأساسي لكافة الاستثناءات |
StopIteration | تستخدم عندما لا تؤشر الطريقة next() على أي غرض من الأغراض. |
SystemExit | تستدعى من قبل التابع sys.exit() |
StandardError | الصف الأساسي لكافة الاستثناءات ماعدا StopIteration و SystemExit |
ArithmeticError | الصف الأساسي لكافة الأخطاء الخاصة بالحساب الرقمي. |
OverflowError | تستدعى عندما يتجاوز الحساب الحد الأعظمي للنموذج الرقمي. |
FloatingPointError | تستدعى عندما يفشل حساب الفاصلة العائمة. |
ZeroDivisonError | تستدعى عندما يحدث التفسيم على الصفر من أجل كلفة النماذج الرقمية. |
AssertionError | تستدعى في حالة فشل تعليمة التأكيد. |
AttributeError | تستدعى عند فشل مرجع المساهمة أو الإسناد. |
EOFError | تستدعى عندما لا يكون هناك دخل من التابع raw_input() أو من التابع input() وتم الوصول إلى نهاية الملف. |
ImportError | تستدعى عند فشل تعليمات الاستدعاء. |
KeyboardInterrupt | تستدعى عند تنفيذ برنامج المقاطعة وعادة بضغط Ctrl+c |
LookupError | الصف الأساسي من أجل كافة أخطاء البحث. |
IndexError KeyError | تستدعى عندما لا يتم إيجاد المؤشر في التتالي. تستدعى عند عدم وجود مفتاح مخصص في القاموس. |
NameError | تستدعى عند عدم وجود المعرف في الفراغ الاسمي الموضعي او العام. |
UnboundLocalError EnvironmentError | تستدعى عند محاولة إسناد متحول موضعي ضمن التابع او الطريقة ولكن دون قيمة مسندة له. الصف الأساسي لكافة الاستثناءات التي تحدث خارج بيئة بايثون. |
IOError IOError | تستدعى عند فشل عملية الدخل والخرج. تستدعى من أجل أخطاء مرتبطة بالنظام. |
SyntaxError IndentationError | تستدعى عند وجود خطأ برمجي. تستدعى عندما لا يتم التعريف بشكل مناسب. |
SystemError | تستدعى عندما يكتشف المترجم مشكلة داخلية ولكن عتد حدوث هذا الخطأ فإن المترجم لا يخرج من البرنامج. |
SystemExit | تستدعى عندما ينهي استخدام المترجم من قبل التابع sys.exit() . |
ValueError | تستدعى عندما يكون للتابع المبني من أجل نموذج البيانات نموذج صالح من المدخلات . |
RuntimeError | تستدعى لا يصنف الخطأ المتولد ضمن أي صنف من الأصناف. |
NotImplementedError | تستدعى عندما طريقة ال abstract تكون غير مطبقة فعلياً (تطبق هذه الطريقة في حالة وجود صف موروث). |
التأكيدات في بايثون
التأكيد عبارة عن تفحص يقوم به المستخدم عند اختبار البرنامج ويمكن تشغيله وإيقافه. الطريقة الأسهل لتفعيل الاختبار هي بإسنادها إلى التعليمة raise-ifعندها يتم تفحص التعبير المستهدف وإذا كانت النتيجة خاطئة فإنه يتم استدعاء الاستثناء.
عادة يقوم المبرمجون بوضع التأكيدات في بداية التابع لتفحص الدخل الصالح للعمل وبعدها يتم استدعاء التابع لتفحص الدخل الصالح.
التعليمة assert
عندما يتم استدعاء هذه التعليمة فإن بايثون تقوم بتقييم التعبير المرافق والذي يؤمل أن يكون صحيحاً وإذا كان خاطئاً فإنه يتم استدعاء الاستثناء AssertionError .
الشيفرة البرمجية –
assert Expression[, Arguments]
إذا فشل التأكيد فإن بايثون تستخدم ArgumentExpression كمدخل لـ AssertionError ولها استثناءات يمكن التعامل معها مثل أي استثناءات اخرى باستخدام التعليمة try-except ولكن إذا لم يتم التعامل معها فإنه يتم إنهاء البرنامج.
مثال
#!/usr/bin/python
def KelvinToFahrenheit(Temperature):
assert (Temperature>=0),"Colder than absolute zero!"
return ((Temperature-273)*1.8)+32
print KelvinToFahrenheit(273)
print int(KelvinToFahrenheit(505.78))
print KelvinToFahrenheit(-5)
فتظهر النتيجة التالية
32.0
451
Traceback (most recent call last):
File "test.py", line 9, in
print KelvinToFahrenheit(-5)
File "test.py", line 4, in KelvinToFahrenheit
assert (Temperature >= 0),"Colder than absolute zero!"
AssertionError: Colder than absolute zero!
ما هو الاستثناء ؟
الاستثناء هو فعل يحدث خلال تنفيذ البرنامج وفق التعليمات التي تتدفق بشكل طبيعي وبشكل عام عندما يتعرض بايثون لأية عملية لا يمكنه التعامل معها عندها يحدث الاستثناء. فالاستثناء هو غرض في بايثون يمثل الخطأ الحاصل. وعند حصول الاستثناء يجب التعامل معه فوراً أو يتم إنهاء البرنامج.
التعامل مع الاستثناء
عند وجود بعض الشيفرات البرمجية والتي من الممكن أن تسبب حدوث الاستثناء فإنه يمكن للمستخدم وضع هذه الشيفرة التي يمكن تسميتها الشيفرة المشبوهة ضمن كتلة try وبعد هذه الكتلة يتم تضمين التعليمة except والتي تتبع بكتلة من الشيفرات التي تتعامل مع المشكلة قدر المستطاع.
الشيفرة البرمجية
try:
You do your operations here;
......................
except ExceptionI:
If there is ExceptionI, then execute this block.
except ExceptionII:
If there is ExceptionII,then execute this block.
......................
else:
If there is no exception then execute this block.
بعض النقاط التوضيحية حول هذه الشيفرة البرمجية:
- التعليمة try يمكن أن تحوي على تعليمات استثناء متعددة ويعتبر هذا مفيداً عندما تحتوي الكتلة على عدة تعليمات يمكن أن ينتج عنها استثناءات متعددة.
- من الممكن تضمين عبارة استثناء مولدة والتي يمكنها التعامل مع أي استثناء.
- بعد عبارة الاستثناء يمكن تضمين عبارة else- ويتم تنفيذ الشيفرة ضمنها إذا لم تسبب الشيفرة الموجودة ضمن كتلة ال try أي استثناء.
- الكتلة else- مكان جيد للشيفرة التي لا تحتاج حماية من الكتلة try-.
مثال
#!/usr/bin/python
try:
fh= open("testfile","w")
fh.write("This is my test file for exception handling!!")
except IOError:
print "Error: can\'t find file or read data"
else:
print "Written content in the file successfully"
fh.close()
فتظهر النتيجة التالية
Written content in the file successfully
مثال
في المثال التالي تتم محاولة فتح ملف عند تعذر الكتابة لذلك ينتج الاستثناء
#!/usr/bin/python
try:
fh= open("testfile","r")
fh.write("This is my test file for exception handling!!")
except IOError:
print "Error: can\'t find file or read data"
else:
print "Written content in the file successfully"
فتظهر النتيجة التالية
Error: can't find file or read data
العبارة except دون أية استثناءات تعرف هذه العبارة وفق التالي
try:
You do your operations here;
......................
except:
If there is any exception,then execute this block.
......................
else:
If there is no exception then execute this block.
هذه العبارة تلتقط كافة الاستثناءات التي تحدث ولكن استخدامها غير محبذ من قبل المبرمجين فهي لا تمكن المبرمج من معرفة السبب الأساسي للمشكلة الحاصلة.
العبارة except مع استثناءات متعددة
تعرف وفق التالي
try:
You do your operations here;
......................
except(Exception1[,Exception2[,...ExceptionN]]]):
If there is any exception from the given exception list,
then execute this block.
......................
else:
If there is no exception then execute this block.
العبارة try-finally
تعتبر هذه العبارة مكاناً مناسباً لوضع أية شيفرة برمجية يجب تنفيذها وسواء أعادت هذه العبارة استثناءاً أم لا فإن الشيفرة البرمجية لها هي
try:
You do your operations here;
......................
Due to any exception,this may be skipped.
finally:
This would always be executed.
......................
ملاحظة
لا يمكن استخدام العبارة else بشكل مترافق مع العبارة finally .
مثال
#!/usr/bin/python
try:
fh= open("testfile","w")
fh.write("This is my test file for exception handling!!")
finally:
print"Error: can\'t find file or read data"
فتظهر النتيجة التالية
Error: can't find file or read data
مثال
#!/usr/bin/python
try:
fh= open("testfile","w")
try:
fh.write("This is my test file for exception handling!!")
finally:
print"Going to close the file"
fh.close()
except IOError:
print"Error: can\'t find file or read data"
عندما يتم وضع استثناء ضمن كتلة try فإن التنفيذ يتجاوز وبشكل تلقائي إلى الكتلة finallyوعندما يتم تنفيذ كافة التعليمات في كتلة ال finally
فإنه يتم استدعاء الاستثناء مرة أخرى ويتم التعامل معه ضمن تعليمات ال except إذا كان موجوداً ضمن الطبقة العليا التالية من التعليمة try-except.
المدخل الخاص بالاستثناء
المدخل الخاص بالاستثناء ما هو إلا قيمة تحمل معلومات إضافية حول المشكلة الحاصلة ومحتوى هذا المدخل تختلف وفقاً للاستثناء.
يتم الحصول على مدخل الاستثناء متحول ضمن عبارة الاستثناء كالتالي:
try:
You do your operations here;
......................
except ExceptionType, Argument:
You can print value of Argument here...
إذا تمت كتابة الشيفرة من أجل استثناء واحد فقط فإنه من الممكن وجود متحول يتبع اسم الاستثناء في تعليمة except وإذا كانت الشيفرة لعدة استثناءات فإنه من الممكن وجود متحول يتبع صف الاستثناء.
يمكن لهذا المتحول أن يتلقى قيمة الاستثناء والتي تحتوي على القسم الأكبر من سبب حدوث المشكلة. ويمكن للمتحول أن يتلقى قيمة واحدة أو عدة قيم من الصف والذي يحوي عادة السلسلة الخاطئة والرقم الخاطئ والموقع الخاطئ.
مثال
#!/usr/bin/python
# Define a function here.
def temp_convert(var):
try:
return int(var)
except ValueError, Argument:
print"The argument does not contain numbers\n", Argument
# Call above function here.
temp_convert("xyz");
فتظهر النتيجة التالية
The argument does not contain numbers
invalid literal for int() with base 10: 'xyz'
استدعاء الاستثناءات
يتم ذلك باستخدام عدة طرق وفق تعليمة الاستدعاء.
الشيفرة البرمجية
raise[Exception[,args[,traceback]]]
هنا Exceptionهي نموذج من الاستثناء و argument هي قيمة مدخل الاستثناء وهو اختياري وفي حال لم يوضع بشكل صريح فإن مدخل الاستثناء لاشيء.
مثال
يمكن أن يكون الاستثناء سلسلة أو صفاً أو غرضاً ولكنها في المعظم صفوف مع مدخلات تمثل مسافة الصف كما ان تعريف استثناءات جديدة أمر سهل يتم وفق التالي:
def functionName( level ):
if level <1:
raise "Invalid level!", level
# The code below to this would not be executed
# if we raise the exception
مثال
من أجل التقاط الاستثناء السابق يجب كتابة عبارة الاستثناء كالتالي-
try:
Business Logic here...
except "Invalid level!":
Exception handling here...
else:
Rest of the code here...
الاستثناءات المعرفة من قبل المستخدم
يتم ذلك باشتقاق الصفوف من الاستثناءات المبنية المعيارية.
في المثال التالي يتم إنشاء الصف والذي هو صف فرعي من RuntimeError وهو مفيد عند الحاجة لعرض معلومات مفصلة اكثر عند التقاط الاستثناء.
في الكتلة try يتم استدعاء الاستثناء المعرف من قبل المستخدم والتقاطه ضمن كتلة الاستثناء. يستخدم المتحول e لإنشاء المسافة ضمن الصف Networkerror .
class Networkerror(RuntimeError):
def __init__(self, arg):
self.args=arg
لذلك عندما يتم تعريف الصف كما في الأعلى فإنه يمكن استدعاء الاستثناء كالتالي-
try:
raise Networkerror("Bad hostname")
except Networkerror,e:
print e.args
ليست هناك تعليقات:
إرسال تعليق