2.25. טיפול בשגיאות¶
רוב בעיות זמן הריצה ב-Python צפות כחריגות (exceptions) – דרך בעלת שם ומובנית לדווח שמשהו השתבש. ValueError, TypeError, KeyError, OSError, MemoryError הן כולן דוגמאות; כל אחת היא מחלקה, וזריקה (raising) של אחת מהן עוצרת את הקריאה הנוכחית ומחפשת מטפל בקוד הסובב.
2.25.1. try / except¶
עטפו בלוק קוד ב-try כדי לתפוס כל חריגה שהוא זורק:
try:
n = int(input_text)
except ValueError:
n = 0
אם המרת ה-int(...) נכשלת, השליטה קופצת לבלוק ה-except במקום להפיץ את השגיאה הלאה. אם input_text היה מחרוזת מספר שלם תקפה, בלוק ה-except מדולג.
ל-try יחיד יכולים להיות מספר בלוקי except, שכל אחד תופס סוג שגיאה שונה:
try:
value = data[key]
except KeyError:
value = None
except TypeError:
value = -1
Python מתאים לפי הסדר; הראשון שמחלקת החריגה שלו מתאימה מטפל בבעיה. תפיסת Exception (מחלקת הבסיס של כמעט הכל) מטפלת בכל שגיאה; שמרו זאת לשכבה החיצונית ביותר של תוכנית שבה החלופה היא קריסה.
אזהרה
except: חשוף (ללא מחלקה אחרי מילת המפתח) תופס גם את KeyboardInterrupt – החריגה שה-IDE שולח כאשר אתם לוחצים על כפתור ה-stop שלו כדי להפסיק סקריפט רץ. לולאה עטופה ב-except: pass חשוף תבלע את ההפסקה ותמשיך לרוץ, ולא תשאיר דרך לעצור את הסקריפט מלבד הפעלה מחדש של המתח.
העדיפו except Exception: על פני except: חשוף כאשר אתם באמת צריכים לתפוס באופן רחב. KeyboardInterrupt יורש מ-BaseException, ולא מ-Exception, כך ש-except Exception: משאיר את כפתור ה-stop פעיל.
2.25.1.1. בחינת החריגה¶
כדי לקרוא את ההודעה המצורפת לחריגה, תנו לה שם עם as:
try:
f = open("data.txt")
except OSError as e:
print("could not open file:", e)
המשתנה שנקשר על ידי as תקף רק בתוך בלוק ה-except.
2.25.2. else ו-finally¶
לבלוק try יש שתי תוספות אופציונליות.
else רץ רק כאשר ה-try הסתיים בלי לזרוק חריגה:
try:
value = compute()
except ValueError:
print("bad input")
else:
print("got", value)
הצבת ”מה לעשות כשזה עבד“ ב-else שומרת על בלוק ה-try צר – רק השורה שעלולה להיכשל שייכת ל-try.
finally רץ בסוף לא משנה מה – בין אם ה-try הצליח, זרק וטופל, או זרק ועומד להתפשט:
try:
do_work()
finally:
cleanup()
finally תמיד רץ. else רץ רק במסלול הלא-חריג.¶
עבור רוב תבניות הקצאה/שחרור, העדיפו מנהל הקשר על פני זוג try / finally – המשאב עצמו מנהל את הניקוי שלו.
2.25.3. חריגות מובנות נפוצות¶
רשימה קצרה של החריגות שתיתקלו בהן לעיתים קרובות:
ValueError– טיפוס נכון, ערך שגוי (bytes([300])– 300 הוא הטיפוס הנכון, אבל מחוץ לטווח הבייט התקף של 0..255).TypeError– טיפוס שגוי לחלוטין (len(42)).IndexError– אינדקס מעבר לסוף של רצף.AttributeError– גישה לתכונה שאינה קיימת ("abc".foo).OSError– כשל מערכת קבצים או קלט/פלט.MemoryError– אזל ה-heap. בזמן ריצה מוגבל זיכרון, זה יכול לקרות במהלך פעולה רגילה – לא רק במקרים פתולוגיים.