Kodokon kodokon.com

الأخطاء والاستثناءات: try، except، raise

التقط الأعطال المتوقَّعة باستخدام try/except/else/finally، وأطلق استثناءاتك الخاصة للإشارة إلى بيانات غير صالحة.

9 دقيقة · 3 أسئلة

افتح هذا الدرس في Kodokon

البرنامج الحقيقي يفشل: ملف مفقود، ومُدخَل غير صالح، وشبكة تنقطع. وتشير بايثون إلى هذه الحالات بـالاستثناءات، التي تقاطع التنفيذ وتنتشر صعودًا في مكدس النداءات حتى تلتقطها كتلة try/except. الانعكاس الاحترافي: التقط الاستثناء الأكثر تحديدًا الممكن، وأقرب ما يمكن من المكان الذي تعرف فيه ما ينبغي فعله.

PYTHON
def parse_age(text):
    try:
        return int(text)
    except ValueError:
        return None

print(parse_age("34"))      # 34
print(parse_age("thirty"))  # None
نلتقط ValueError بدقة، لا كل الأخطاء.

تحتوي الكتلة الكاملة على أربعة فروع. تضم try الشيفرة المحفوفة بالمخاطر، وتعالج except العطل، وتُنفَّذ else فقط إذا لم يُطلَق أيّ استثناء، وتُنفَّذ finally في كل الحالات - وهي مثالية لتحرير مورد أو للتسجيل. والفائدة من else: إبقاء try في حدّها الأدنى، لترى من نظرة واحدة أيّ سطر يمكن أن يفشل.

PYTHON
values = ["10", "abc", "25"]
total = 0

for value in values:
    try:
        number = int(value)
    except ValueError:
        print(f"Skip : {value}")
    else:
        total += number
    finally:
        print(f"Process : {value}")

print(total)  # 35
تُنفَّذ else فقط عندما لا يوجد خطأ؛ أما finally فتُنفَّذ دائمًا.

يمكن لدوالك أيضًا أن تُطلق استثناءاتها الخاصة باستخدام raise، حالما تكون إحدى البيانات المستلَمة غير صالحة: فالفشل الفوري برسالة واضحة أفضل من إنتاج نتيجة خاطئة. عرِّف صنفًا مخصصًا يرث من Exception: عندئذٍ سيتمكن المُستدعي من التقاطه تحديدًا، دون اعتراض أخطاء أخرى عن غير قصد.

PYTHON
class EmptyCartError(Exception):
    pass

def checkout(items):
    if not items:
        raise EmptyCartError("Empty cart.")
    return round(sum(items), 2)

try:
    print(checkout([]))
except EmptyCartError as error:
    print(f"Error : {error}")
استثناء مخصص لمنطق العمل يجعل العطل صريحًا ومحدَّدًا.

اختبار المعرفة

تأكّد من أنك تذكّرت النقاط الأساسية في هذا الدرس.

  1. متى تُنفَّذ كتلة else في try/except؟
    • فقط إذا لم يُطلَق أيّ استثناء في try
    • فقط إذا التُقط استثناء
    • في كل الحالات، بعد try
  2. في أيّ الحالات تُنفَّذ كتلة finally؟
    • فقط إذا أُطلق استثناء
    • فقط إذا لم يُطلَق أيّ استثناء
    • في كل الحالات، سواء وقع استثناء أم لا
  3. لماذا نتجنّب except: مجرّدة تلتقط كل شيء؟
    • لأنها تخفي أخطاءً برمجية حقيقية وتجعل التصحيح صعبًا جدًا
    • لأنها أبطأ من except مُستهدَفة
    • لأنها لا تعمل إلا مع استثناءات المكتبة القياسية