1. نظرة عامة على معالجة الاستثناءات في بايثون
ما هي معالجة الاستثناءات في بايثون؟
أثناء تشغيل البرنامج، قد تحدث أخطاء غير متوقعة. يُطلق على هذه الأخطاء “استثناءات”، وعند حدوث استثناء عادةً ما يتوقف البرنامج عن العمل. في بايثون، تم توفير معالجة الاستثناءات للتعامل مع هذه الحالات. باستخدام معالجة الاستثناءات، يمكن للبرنامج الاستمرار في العمل والتعامل مع الأخطاء بشكل مناسب عند مواجهتها.
لماذا معالجة الاستثناءات مهمة؟
تعتبر معالجة الاستثناءات مهمة حتى يستمر البرنامج في العمل بطريقة سهلة للمستخدم، حتى عند حدوث خطأ. كما تساعد في تحديد أسباب الأخطاء وتسهل عملية تصحيحها، مما يؤدي إلى إنشاء برامج أكثر موثوقية.
2. ما هي عبارة try-except
؟
البنية الأساسية
تُستخدم عبارة try-except
في بايثون لكتابة الأكواد التي قد ينتج عنها أخطاء داخل كتلة try
، وإذا حدث خطأ يتم تنفيذ كتلة except
. فيما يلي البنية الأساسية:
try:
# كود قد ينتج عنه خطأ
except SomeError:
# كود لمعالجة الخطأ
إذا تم تنفيذ الكود داخل كتلة try
بنجاح، يتم تجاهل except
، أما إذا حدث خطأ، فسيتم التعامل معه حسب نوع الاستثناء المحدد.
مثال شائع: خطأ القسمة على الصفر
إذا حاولت القسمة على صفر، سيظهر خطأ من نوع ZeroDivisionError
. يمكن معالجة هذا الخطأ كالتالي:
try:
result = 10 / 0
except ZeroDivisionError:
print("لا يمكن القسمة على الصفر")

3. أشهر الاستثناءات وكيفية التعامل معها
1. ZeroDivisionError
يحدث هذا الاستثناء عند محاولة القسمة على صفر. على سبيل المثال، إذا حاولت قسمة رقم على صفر، سيقوم بايثون بإظهار ZeroDivisionError
تلقائيًا.
try:
result = 10 / 0
except ZeroDivisionError:
print("لا يمكن القسمة على الصفر")
2. ValueError
يظهر ValueError
عند تمرير قيمة غير مناسبة لدالة أو عملية ما. في المثال التالي، يتم محاولة تحويل نص غير قابل للتحويل إلى رقم باستخدام int()
.
try:
num = int("not_a_number")
except ValueError:
print("قيمة غير صالحة")
3. كيفية التعامل مع عدة استثناءات
إذا كنت ترغب في معالجة عدة استثناءات في نفس الوقت، يمكنك ذلك من خلال جمعها في except
واحدة:
try:
result = 10 / "string"
except (ZeroDivisionError, TypeError):
print("حدث خطأ")
4. الحصول على تفاصيل الخطأ باستخدام كائن الاستثناء
الحصول على كائن الاستثناء باستخدام as
يمكنك استخدام الكلمة المفتاحية as
في عبارة except
للحصول على كائن الاستثناء. بذلك يمكنك عرض تفاصيل الخطأ أو تسجيلها في سجل الأخطاء (اللوغ).
try:
a = 10 / 0
except ZeroDivisionError as e:
print(f"حدث خطأ: {e}")
في هذا المثال، عند حدوث ZeroDivisionError
، يتم تخزين رسالة الخطأ في المتغير e
ويمكن عرض التفاصيل.
5. كيفية استخدام كتلة finally
ما هي finally
؟
تُستخدم كتلة finally
لكتابة الأكواد التي يجب تنفيذها مهما حدث، سواء وقع استثناء أم لا. تعتبر مثالية عند العمل مع الملفات أو قواعد البيانات لضمان إغلاق الموارد.
try:
file = open("test.txt", "r")
except FileNotFoundError:
print("الملف غير موجود")
finally:
print("تم إنهاء عملية التعامل مع الملف")
تنظيف الموارد
تُستخدم finally
عادةً لتحرير الموارد في نهاية البرنامج. على سبيل المثال، لضمان إغلاق الملف بعد استخدامه:
try:
file = open("data.txt", "r")
# عمليات على الملف
finally:
file.close()
بهذه الطريقة، يمكنك التأكد من أن الملف سيتم إغلاقه بشكل صحيح باستخدام كتلة finally
.
6. رفع الاستثناءات يدويًا باستخدام raise
دور raise
تُمكنك عبارة raise
من توليد استثناء يدويًا في حالات معينة. يمكنك استخدامها للتحقق من صحة القيم أو الشروط وإظهار الأخطاء عند الحاجة.
def check_value(value):
if value < 0:
raise ValueError("القيم السالبة غير مسموحة")
مثال على استثناء مخصص
من خلال رفع الأخطاء في حالات معينة، يمكنك منع إدخال بيانات غير صحيحة وبالتالي تجنب حدوث مشاكل غير متوقعة.

7. أفضل الممارسات لمعالجة الاستثناءات في بايثون
1. تجنب الإفراط في استخدام معالجة الاستثناءات
الإفراط في استخدام معالجة الاستثناءات قد يؤدي إلى تقليل قابلية قراءة الكود ويصعب عملية تصحيحه. استخدمها فقط في الأماكن التي يُحتمل فيها حدوث خطأ، وتجنب استخدامها في التدفق الطبيعي للبرنامج.
2. تسجيل الأخطاء باستخدام السجلات (logging)
من المهم تسجيل رسائل الأخطاء عند حدوث استثناءات حتى تتمكن من تتبع أسبابها لاحقًا. فيما يلي مثال باستخدام وحدة logging
في بايثون:
import logging
try:
a = 10 / 0
except ZeroDivisionError as e:
logging.error(f"حدث خطأ: {e}")
3. تجنب استخدام except
العامة بشكل مفرط
يفضل دائمًا معالجة أنواع الأخطاء المحددة بدلاً من استخدام except Exception
العامة، لأن ذلك قد يؤدي إلى إخفاء تفاصيل المشكلات. تعامل مع الأخطاء بشكل منفصل قدر الإمكان.