جدول المحتويات
- الاستثناءات مقابل الأخطاء النحوية
- رفع استثناء
- استثناء AssertionError
- كتلة المحاولة والاستثناء: معالجة الاستثناءات
- شرط آخر
- التنظيف بعد الاستخدام أخيرًا
- تلخيص لما سبق
ينتهي برنامج بايثون بمجرد أن يواجه خطأ. في Python ، يمكن أن يكون الخطأ خطأ نحويًا أو استثناءً. في هذه المقالة ، سترى ما هو الاستثناء وكيف يختلف عن الخطأ النحوي. بعد ذلك ، ستتعرف على كيفية رفع الاستثناءات وتقديم التأكيدات. بعد ذلك ، ستنتهي مع عرض توضيحي لمحاولة الاستثناء.
الاستثناءات مقابل الأخطاء النحوية
تحدث أخطاء بناء الجملة عندما يكتشف المحلل اللغوي عبارة غير صحيحة. لاحظ المثال التالي:
>>> print( 0 / 0 ))
File "<stdin>", line 1
print( 0 / 0 ))
^
SyntaxError: invalid syntax
يشير السهم إلى مكان تعرض المحلل اللغوي لخطأ في بناء الجملة. في هذا المثال ، كان هناك قوس واحد أكثر من اللازم. قم بإزالته وتشغيل الكود الخاص بك مرة أخرى:
>>> print( 0 / 0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: integer division or modulo by zero
هذه المرة ، واجهت خطأ استثناء. يحدث هذا النوع من الأخطاء عندما ينتج عن رمز Python الصحيح من الناحية التركيبية خطأ. أشار السطر الأخير من الرسالة إلى نوع خطأ الاستثناء الذي واجهته.
بدلاً من إظهار خطأ استثناء الرسالة ، توضح Python نوع خطأ الاستثناء الذي تمت مواجهته. في هذه الحالة ، كان خطأ ZeroDivisionError. تأتي Python مع العديد من الاستثناءات المضمنة بالإضافة إلى إمكانية إنشاء استثناءات محددة ذاتيًا.
رفع استثناء
يمكننا استخدام الزيادة لطرح استثناء في حالة حدوث شرط. يمكن استكمال البيان مع استثناء مخصص.
إذا كنت تريد إلقاء خطأ عند حدوث حالة معينة باستخدام الزيادة ، فيمكنك القيام بذلك على النحو التالي:
x = 10
if x > 5:
raise Exception('x should not exceed 5. The value of x was: {}'.format(x))
عند تشغيل هذا الرمز ، سيكون الإخراج كما يلي:
Traceback (most recent call last):
File "<input>", line 4, in <module>
Exception: x should not exceed 5. The value of x was: 10
توقف البرنامج وعرض استثناءنا على الشاشة ، مع تقديم أدلة حول الخطأ الذي حدث.
استثناء AssertionError
بدلاً من انتظار تعطل البرنامج في منتصف الطريق ، يمكنك أيضًا البدء بتأكيد في Python. نؤكد أنه تم استيفاء شرط معين. إذا تبين أن هذا الشرط صحيح ، فهذا ممتاز! يمكن أن يستمر البرنامج. إذا تبين أن الشرط خاطئ ، فيمكنك جعل البرنامج يطرح استثناء AssertionError.
ألق نظرة على المثال التالي ، حيث تم التأكيد على أن الكود سيتم تنفيذه على نظام Linux:
import sys
assert ('linux' in sys.platform), "This code runs on Linux only."
إذا قمت بتشغيل هذا الرمز على جهاز Linux ، فسيتم تمرير التأكيد. إذا كنت ستقوم بتشغيل هذا الرمز على جهاز يعمل بنظام Windows ، فستكون نتيجة التأكيد False وستكون النتيجة كما يلي:
Traceback (most recent call last):
File "<input>", line 2, in <module>
AssertionError: This code runs on Linux only.
في هذا المثال ، يعد طرح استثناء AssertionError هو آخر شيء سيفعله البرنامج. سيتوقف البرنامج ولن يستمر. ماذا لو لم يكن هذا ما تريده؟
كتلة المحاولة والاستثناء: معالجة الاستثناءات
تُستخدم كتلة try and except في Python للقبض على الاستثناءات ومعالجتها. تنفذ Python التعليمات البرمجية التي تلي تعليمة try كجزء “عادي” من البرنامج. الكود الذي يتبع تعليمة الاستثناء هو استجابة البرنامج لأي استثناءات في عبارة try السابقة.
كما رأيت سابقًا ، عندما تصطدم الشفرة الصحيحة من الناحية التركيبية بخطأ ، فإن Python ستطلق خطأ استثناء. سيؤدي خطأ الاستثناء هذا إلى تعطل البرنامج إذا لم تتم معالجته. يحدد بند الاستثناء كيف يستجيب برنامجك للاستثناءات.
يمكن أن تساعدك الوظيفة التالية في فهم كتلة المحاولة والاستثناء:
def linux_interaction():
assert ('linux' in sys.platform), "Function can only run on Linux systems."
print('Doing something.')
يمكن تشغيل linux_interaction () على نظام Linux فقط. سوف يطرح التأكيد في هذه الوظيفة استثناء AssertionError إذا قمت باستدعائه على نظام تشغيل آخر غير Linux.
يمكنك تجربة الوظيفة باستخدام الكود التالي:
try:
linux_interaction()
except:
pass
الطريقة التي تعاملت بها مع الخطأ هنا هي بتسليمك تمريرة. إذا كنت ستقوم بتشغيل هذا الرمز على جهاز يعمل بنظام Windows ، فستحصل على الإخراج التالي:
ليس لديك شيء. الشيء الجيد هنا هو أن البرنامج لم يتعطل. ولكن سيكون من الجيد معرفة ما إذا كان هناك نوع من الاستثناء يحدث عندما قمت بتشغيل الكود الخاص بك. لتحقيق هذه الغاية ، يمكنك تغيير البطاقة إلى شيء من شأنه أن يولد رسالة إعلامية ، مثل:
try:
linux_interaction()
except:
print('Linux function was not executed')
قم بتنفيذ هذا الرمز على جهاز يعمل بنظام Windows:
Linux function was not executed
عند حدوث استثناء في برنامج يقوم بتشغيل هذه الوظيفة ، سيستمر البرنامج بالإضافة إلى إبلاغك بحقيقة أن استدعاء الوظيفة لم يكن ناجحًا.
ما لم تراه هو نوع الخطأ الذي تم إلقاؤه نتيجة لاستدعاء الوظيفة. لكي ترى الخطأ الذي حدث بالضبط ، ستحتاج إلى اكتشاف الخطأ الذي أحدثته الوظيفة.
الكود التالي هو مثال حيث يمكنك التقاط AssertionError وإخراج تلك الرسالة إلى الشاشة:
try:
linux_interaction()
except AssertionError as error:
print(error)
print('The linux_interaction() function was not executed')
يؤدي تشغيل هذه الوظيفة على جهاز يعمل بنظام Windows إلى ما يلي:
Function can only run on Linux systems.
The linux_interaction() function was not executed
الرسالة الأولى هي AssertionError ، تخبرك أنه لا يمكن تنفيذ الوظيفة إلا على جهاز Linux. تخبرك الرسالة الثانية بالوظيفة التي لم يتم تنفيذها.
في المثال السابق ، قمت باستدعاء دالة كتبتها بنفسك. عند تنفيذ الوظيفة ، اكتشفت استثناء AssertionError وطباعته على الشاشة.
إليك مثال آخر حيث تفتح ملفًا وتستخدم استثناءًا مضمنًا:
try:
with open('file.log') as file:
read_data = file.read()
except:
print('Could not open file.log')
إذا لم يكن file.log موجودًا ، فستخرج كتلة التعليمات البرمجية هذه ما يلي:
Could not open file.log
هذه رسالة إعلامية ، وسيستمر تشغيل برنامجنا. في مستندات Python ، يمكنك أن ترى أن هناك الكثير من الاستثناءات المضمنة التي يمكنك استخدامها هنا. الاستثناء الوحيد الموضح في تلك الصفحة هو ما يلي:
استثناء FileNotFoundError
يُطلق عند طلب ملف أو دليل ولكنه غير موجود. يتوافق مع errno ENOENT.
للقبض على هذا النوع من الاستثناءات وطباعته على الشاشة ، يمكنك استخدام الكود التالي:
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
في هذه الحالة ، إذا لم يكن file.log موجودًا ، فسيكون الإخراج كما يلي:
[Errno 2] No such file or directory: 'file.log'
يمكن أن يكون لديك أكثر من استدعاء دالة في جملة try وتوقع اصطياد استثناءات مختلفة. الشيء الذي يجب ملاحظته هنا هو أن الكود في جملة try سيتوقف بمجرد مواجهة استثناء.
تحذير: Catching Exception يخفي كل الأخطاء … حتى تلك غير المتوقعة تمامًا. هذا هو السبب في أنه يجب عليك تجنب البنود العارية باستثناء البنود في برامج بايثون الخاصة بك. بدلاً من ذلك ، سترغب في الرجوع إلى فئات استثناء محددة تريد التقاطها والتعامل معها. يمكنك معرفة المزيد حول سبب اعتبار هذه فكرة جيدة في هذا البرنامج التعليمي.
انظر إلى الكود التالي. هنا ، تقوم أولاً باستدعاء الدالة linux_interaction () ثم تحاول فتح ملف:
try:
linux_interaction()
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
except AssertionError as error:
print(error)
print('Linux linux_interaction() function was not executed')
إذا لم يكن الملف موجودًا ، فسيؤدي تشغيل هذا الرمز على جهاز يعمل بنظام Windows إلى إخراج ما يلي:
Function can only run on Linux systems.
Linux linux_interaction() function was not executed
داخل جملة try ، واجهت استثناء على الفور ولم تصل إلى الجزء الذي تحاول فيه فتح file.log. انظر الآن إلى ما يحدث عند تشغيل الكود على جهاز Linux:
[Errno 2] No such file or directory: 'file.log'
فيما يلي النقاط الرئيسية:
- يتم تنفيذ جملة محاولة حتى النقطة التي يتم فيها مواجهة الاستثناء الأول.
- داخل بند الاستثناء ، أو معالج الاستثناء ، يمكنك تحديد كيفية استجابة البرنامج للاستثناء.
- يمكنك توقع استثناءات متعددة والتمييز بين كيفية استجابة البرنامج لها.
- تجنب استخدام العارية باستثناء الجمل.
شرط آخر
في Python ، باستخدام تعليمة else ، يمكنك توجيه برنامج لتنفيذ كتلة معينة من التعليمات البرمجية فقط في حالة عدم وجود استثناءات.
try:
linux_interaction()
except AssertionError as error:
print(error)
else:
print('Executing the else clause.')
إذا كنت ستقوم بتشغيل هذا الرمز على نظام Linux ، فسيكون الإخراج كما يلي:
Doing something.
Executing the else clause.
نظرًا لأن البرنامج لم يتم تشغيله في أي استثناءات ، تم تنفيذ جملة else.
يمكنك أيضًا محاولة تشغيل التعليمات البرمجية داخل جملة else والتقاط الاستثناءات المحتملة هناك أيضًا:
try:
linux_interaction()
except AssertionError as error:
print(error)
else:
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
إذا كنت ستقوم بتنفيذ هذا الرمز على جهاز Linux ، فستحصل على النتيجة التالية:
Doing something.
[Errno 2] No such file or directory: 'file.log'
من الإخراج ، يمكنك أن ترى أن وظيفة linux_interaction () تعمل. بسبب عدم وجود استثناءات ، تم إجراء محاولة لفتح file.log. هذا الملف غير موجود ، وبدلاً من فتح الملف ، اكتشفت استثناء FileNotFoundError.
التنظيف بعد الاستخدام أخيرًا
تخيل أنه كان عليك دائمًا تنفيذ نوع من الإجراءات للتنظيف بعد تنفيذ التعليمات البرمجية الخاصة بك. تمكنك لغة بايثون من القيام بذلك باستخدام الجملة النهائية.
ألق نظرة على المثال التالي:
try:
linux_interaction()
except AssertionError as error:
print(error)
else:
try:
with open('file.log') as file:
read_data = file.read()
except FileNotFoundError as fnf_error:
print(fnf_error)
finally:
print('Cleaning up, irrespective of any exceptions.')
في الكود السابق ، سيتم تنفيذ كل شيء في الجملة النهائية. لا يهم إذا واجهت استثناء في مكان ما في جمل try أو else. سيؤدي تشغيل الكود السابق على جهاز يعمل بنظام Windows إلى إخراج ما يلي:
Function can only run on Linux systems.
Cleaning up, irrespective of any exceptions.
تلخيص لما سبق
بعد رؤية الفرق بين أخطاء بناء الجملة والاستثناءات ، تعلمت طرقًا مختلفة لرفع الاستثناءات والتقاطها والتعامل معها في Python. في هذه المقالة ، رأيت الخيارات التالية:
- يسمح لك رفع استثناء في أي وقت.
- يمكنك التأكيد من التحقق مما إذا تم استيفاء شرط معين ورمي استثناء إذا لم يكن كذلك.
- في جملة try ، يتم تنفيذ جميع العبارات حتى يتم مواجهة استثناء.
- يتم استخدام ما عدا لالتقاط ومعالجة الاستثناء (الاستثناءات) التي تمت مواجهتها في عبارة try.
- يتيح لك else أقسام التعليمات البرمجية التي يجب تشغيلها فقط عند عدم وجود استثناءات في جملة try.
- يتيح لك أخيرًا تنفيذ أقسام التعليمات البرمجية التي يجب تشغيلها دائمًا ، مع أو بدون أي استثناءات تمت مواجهتها مسبقًا.
نأمل أن تساعدك هذه المقالة في فهم الأدوات الأساسية التي يجب أن تقدمها Python عند التعامل مع الاستثناءات.