14.4 معالجة الاستثناءات
أهداف التعلم
في نهاية هذا القسم، ينبغي أن تكون قادرًا على
- وصف استثنائين قد يحدثان عند قراءة الملفات.
- كتابة تعليمات
try/exceptالتي تعالج الاستثناءات المُضمَّنة.
أخطاء وقت التشغيل
قد تحدث أخطاء متنوعة عند قراءة ملف:
FileNotFoundError: اسم الملف أو المسار غير صالح.IndexError/ValueError: تنسيق الملف غير صالح.- أخطاء أخرى ناتجة عن محتويات ملف غير صالحة.
عند حدوث خطأ، يتوقف البرنامج ويعرض رسالة خطأ.
مثال 14.4
خطأ مطبعي في ملف
يحتوي ملف باسم food_order.txt على المحتويات التالية:
5 sandwiches
4 chips
1 pickle
soft drinks
يتوقع البرنامج التالي أن يبدأ كل سطر في الملف بعدد صحيح:
for line in open("food_order.txt"):
space = line.index(" ")
qty = int(line[:space])
item = line[space+1:-1]
print(qty, item)
للأسف، السطر "soft drinks" لا يبدأ بعدد صحيح. ونتيجة لذلك، يتوقف البرنامج ويعرض رسالة خطأ:
Traceback (most recent call last):
File "food_order.py", line 3
qty = int(line[:space])
ValueError: invalid literal for int() with base 10: 'soft'
مفاهيم تطبيقية
الاستثناءات الشائعة
ما الخطأ الذي قد يحدث في كل موقف؟
استكشاف أعمق
تشرح صفحة الاستثناءات المُضمَّنة في مكتبة بايثون القياسية معنى كل استثناء.
تعليمتا try و except
يمكن تصميم البرامج لمعالجة الاستثناءات، بدلاً من إنهاء عملها. تُنفِّذ تعليمة try شِفرةً قد تُطلق استثناءً. وتُنفِّذ فقرة except شِفرةً استجابةً للاستثناء.
مثال 14.5
محاولة فتح ملف
يطلب البرنامج التالي، المسمى try_open.py، من المستخدم اسم ملف ويعد عدد الأسطر في الملف.
name = input("Enter a filename: ")
try:
file = open(name)
lines = file.readlines()
count = len(lines)
print(name, "has", count, "lines")
except FileNotFoundError:
print("File not found:", name)
print("Have a nice day!")
عند تشغيل هذا البرنامج مع الإدخال try_open.py، وهو اسم ملف البرنامج، يكون الإخراج هو:
Enter a filename: try_open.py
try_open.py has 9 lines
Have a nice day!
إذا لم يكن اسم الملف موجودًا، يُطلَق FileNotFoundError في السطر 3. ثم ينتقل البرنامج إلى فقرة except في السطر 7 ويستمر في العمل. يكون الإخراج الناتج هو:
Enter a filename: try_open.txt
File not found: try_open.txt
Have a nice day!
مفاهيم تطبيقية
التنبؤ بالمخرجات مع الاستثناءات
لكل مقتطف شِفرة، ما هو الإخراج؟
جرّب بنفسك
محلل الأنواع
غالبًا ما تحتاج برامج التحليل إلى العثور على أرقام في كميات كبيرة من النصوص. كيف يمكن للبرنامج أن يحدد ما إذا كانت سلسلة نصية مثل "123.45" تمثل رقمًا؟ أحد الأساليب هو استخدام الاستثناءات:
- حاول تحويل السلسلة النصية إلى عدد صحيح. إذا لم يُطلَق
ValueError، فإن السلسلة النصية تمثل عددًا صحيحًا. - وإلا، حاول تحويل السلسلة النصية إلى عدد عشري. إذا لم يُطلَق
ValueError، فإن السلسلة النصية تمثل عددًا عشريًا. - وإلا، فإن السلسلة النصية لا تمثل رقمًا.
نفّذ الدالّة get_type() باستخدام هذا الأسلوب. تستدعي الكتلة الرئيسية المتوفرة الدالّة get_type() لكل كلمة في ملف. يجب أن تُرجع الدالّة get_type() إما "int"، أو "float"، أو "str"، بناءً على الكلمة. الإخراج لملف data.txt المتوفر هو:
str: Hello
int: 100
str: times!
float: 3.14159
str: is
str: pi.
جرّب بنفسك
الدول التي تحتوي على كلمة United
اكتب برنامجًا يطلب من المستخدم إدخال كلمة واسم ملف. يجب أن يطبع البرنامج كل سطر من الملف يحتوي على الكلمة. إليك مثال لتشغيل البرنامج (إدخال المستخدم بالخط العريض):
Enter a word: United
Enter a filename: countries.csv
United Arab Emirates,9890402,83600,118
United Kingdom,67886011,241930,281
United States of America,331002651,9147420,36
يستخدم هذا المثال ملفًا باسم countries.csv بناءً على القائمة الأبجدية للدول من Worldometer. يتضمن كل سطر في الملف اسم الدولة، وعدد السكان، والمساحة البرية، والكثافة السكانية، مفصولة بفواصل.
قد يكتب المستخدم اسم الملف بشكل غير صحيح (مثال: countries.txt بدلاً من countries.csv). يجب أن يعرض برنامجك رسالة خطأ إذا لم يتم العثور على الملف، ويستمر في مطالبة المستخدم بإدخال اسم ملف حتى يتم العثور عليه:
...
Enter a filename: countries
File not found: countries
Enter a filename: countries.txt
File not found: countries.txt
Enter a filename: countries.csv
...
تلميح: حاول فتح الملف المحدد من قبل المستخدم. يُطلَق FileNotFoundError إذا كان اسم الملف غير صالح.