טיפול בחריגים בפייתון באמצעות הבלוקים try ו-except
טיפול בחריגים Exceptions היא דרך מקובלת לטיפול בשגיאות באופן אלגנטי. לדוגמה, אם נכשל הניסיון שלנו להתחבר למסד הנתונים, אנחנו יכולים לטפל בשגיאה ע"י הפנייה למקור נתונים חלופי או לפחות לספק הודעת שגיאה אינפורמטיבית.
במדריך זה, הסבר כיצד לטפל בחריגים בפייתון. אדגים את הנושא דרך טיפול בשגיאה הנגרמת כשמנסים לחלק באפס.
ראשית, נראה מה עלול לקרות אם מנסים לחלק באפס ללא שימוש ב-exceptions.
x = 5
y = 0
print(x / y)
התוצאה:
Traceback (most recent call last): File "string", line 3, in module ZeroDivisionError: division by zero
קיבלנו הודעה מכוערת המבטאת שגיאה פטלית שגרמה לסקריפט להפסיק לרוץ.
כדי למנוע את הבעיה נוכל להשתמש בגישה של טיפול בחריגים במסגרתה התוכנה תוכל להראות הודעת שגיאה סבירה יותר למשתמש או לספק קוד חליפי. לדוגמה, חלוקה במספר הקרוב ל-0 או במקרה של ניסיון ליצור קשר עם מסד נתונים שאינו מגיב, לנסות לתקשר עם מסד נתונים חליפי.
צמד הבלוקים try ו-except לטיפול בחריגים
מילות המפתח try ו-except משמשות לטיפול בחריגים. כל אחת מהם תוחמת בלוק. כך נראה המקרה הכללי:
try: # run the code except Exception: # what to do in the case of error
- בתוך בלוק try התוכנה מנסה להריץ קוד.
לדוגמה:
try:
x = 5
y = 0
print(x / y)
except Exception:
print('problem in division')
והתוצאה:
problem in division
בזכות השימוש בטיפול בחריגים הקוד מנע את הרצת הקוד בתוך בלוק try ודילג ישר להדפסת הודעת השגיאה בתוך בלוק except.
החריגים המובנים שמספק פייתון Built-in Exceptions
הודעת השגיאה שסיפקנו היא כללית, ולא ברור מה לא בסדר בקוד. כדי להיות יותר ספציפיים רצוי להשתמש בחריגים הסטנדרטיים שמספק פייתון. לדוגמה, החריג ZeroDivisionError המשמש במקרה של חלוקה באפס:
try:
x = 5
y = 0
print(x / y)
except ZeroDivisionError:
print('Exception! do not divide by zero')
התוצאה:
Exception! do not divide by zero
עוזרת לנו להבין שהבעיה היא שהתוכנה ניסתה לחלק באפס.
במקום לכתוב את הודעות השגיאה בעצמנו, אפשר להשתמש בהודעות השגיאה שמספק פייתון באמצעות התחביר הבא:
try:
x = 5
y = 0
print(x / y)
except ZeroDivisionError as e:
print(e)
התוצאה:
division by zero
את הודעת השגיאה מספק פייתון.
ראינו את החריג ZeroDivisionError שמספק פייתון למקרה של ניסיון לחלק באפס. חריגים נוספים הם:
TypeError
כאשר אנחנו מנסים להעביר סוג נתונים שגוי. לדוגמה, לבצע פעולה חשבונית על מחרוזת.
IndexError
במידה ואנחנו מנסים לגשת לפריט של רשימה שאינו קיים.
NameError
כשמנסים להשתמש במשתנה שלא קיים.
את הרשימה המלאה של ה-Exception שמספק פייתון תוכל לראות פה.
טיפול במספר חריגים
נחזור לדוגמה שלנו ונראה מה קורה כשאנחנו לא מגדירים את אחד המשתנים:
try:
y = 0
print(x / y)
except ZeroDivisionError as e:
print(e)
התוצאה הודעת שגיאה בגלל שאנחנו מנסים להשתמש במשתנה לא מוגדר:
Traceback (most recent call last): File "string", line 3, in module NameError: name 'x' is not defined
למה אנחנו מקבלים שגיאה במקום שבלוק ה-except יקבל פיקוד? זה בגלל שהחריגה שהגדרנו היא של חלוקה באפס. נוסיף קוד לטיפול בחריגה של משתנה לא מוגדר:
try:
y = 0
print(x / y)
except ZeroDivisionError as e:
print(e)
except NameError as e:
print(e)
התוצאה:
name 'x' is not defined
היא הודעת השגיאה המובנה של פייתון לטיפול בחריגים מסוג NameError כאשר בלוק try נתקל במשתנה לא מוכר.
לסיכום, ניתן להגדיר יותר מאשר חריג אחד. כל חריג יוגדר בבלוק try נפרד.
העלאת חריגות באמצעות raise
עד כה ראינו כיצד ניתן להשתמש בבלוקים של try...except לטפל בשגיאות אבל אנחנו יכולים להגדיר מקרים שבהם נרצה שהקוד שלנו יזרוק חריג. את זה נעשה באמצעות הפקודה raise.
בדוגמה הבאה במידה והערך של המשתנה y הוא גבוה מ-500 נזרוק חריגה:
try:
x = 5
y = 501
if y > 500:
raise Exception('Exception thrown')
print(x / y)
except Exception as e:
print(e)
התוצאה:
Exception thrown
הבלוק else - רץ בהעדר חריגות
בתוך הבלוק else נגדיר לפייתון את הקוד שצריך להריץ במקרה של העדר חריגות. לדוגמה:
try:
x = 5
y = 1
print(x / y)
except ZeroDivisionError as e:
print(e)
else:
print('Running the else block')
התוצאה:
Running the else block
בגלל שהתוכנה לא נתקלה בבעיות היא הריצה גם את הבלוק else.
נסכם:
בלוק finally - לנקות את מה שנשאר
לעיתים נרצה לבצע פעולה מסוימת בין אם התוכנה הצליחה לרוץ או נכשלה. לדוגמה, נרצה לסגור את התקשורת עם מסד הנתונים בכל מקרה. נשתמש בקוד finally כדי להגדיר קוד שתמיד רץ בסוף:
try:
x = 5
y = 0
print(x / y)
except ZeroDivisionError as e:
print(e)
else:
print('Running the else block')
finally:
print('Always running')
תוצאה:
division by zero Always running
בלוק finally תמיד ירוץ ובכלל לא משנה אם הקוד בבלוקים הקודמים הצליח לבצע את העבודה ללא חריגים.
נסכם:
טיפול בחריגים לעומת שימוש בתנאים
למתכנתים מתחילים הנושא של טיפול בחריגים באמצעות בלוקים try...except נראה דומה מדי לשימוש בתנאים if, elif ו-else, והשאלה מתי להשתמש בכל אחד מסגנונות הקוד. התשובה היא שהשימוש תלוי במקרה. אם החלופה היא נדירה נעדיף טיפול בחריגים. לדוגמה: כשאנחנו מנסים ליצור תקשורת עם מסד נתונים, להשתמש בקובץ, לתפוס מידע שמקורו ברשת האינטרנט או שאנחנו תלויים במידע שמזין המשתמש.
אם החלופה נדירה נעדיף טיפול בחריגים על פני שימוש בתנאים.
לכל המדריכים בסדרה ללימוד פייתון
אהבתם? לא אהבתם? דרגו!
0 הצבעות, ממוצע 0 מתוך 5 כוכבים
המדריכים באתר עוסקים בנושאי תכנות ופיתוח אישי. הקוד שמוצג משמש להדגמה ולצרכי לימוד. התוכן והקוד המוצגים באתר נבדקו בקפידה ונמצאו תקינים. אבל ייתכן ששימוש במערכות שונות, דוגמת דפדפן או מערכת הפעלה שונה ולאור השינויים הטכנולוגיים התכופים בעולם שבו אנו חיים יגרום לתוצאות שונות מהמצופה. בכל מקרה, אין בעל האתר נושא באחריות לכל שיבוש או שימוש לא אחראי בתכנים הלימודיים באתר.
למרות האמור לעיל, ומתוך רצון טוב, אם נתקלת בקשיים ביישום הקוד באתר מפאת מה שנראה לך כשגיאה או כחוסר עקביות נא להשאיר תגובה עם פירוט הבעיה באזור התגובות בתחתית המדריכים. זה יכול לעזור למשתמשים אחרים שנתקלו באותה בעיה ואם אני רואה שהבעיה עקרונית אני עשוי לערוך התאמה במדריך או להסיר אותו כדי להימנע מהטעיית הציבור.
שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.
המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?
השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.