ברוכים הבאים ליחידת הלימוד "טיפול בקבצים וטיפול בשגיאות" בקורס "תכנות וניתוח נתונים בשפת פייתון" (20606). יחידה זו חיונית לפיתוח תוכניות חזקות ואמינות, המסוגלות לתקשר עם העולם החיצוני (באמצעות קבצים) ולטפל בתרחישים בלתי צפויים (באמצעות טיפול בחריגות). הבנה מעמיקה של נושאים אלו היא קריטית לא רק לכתיבת קוד נקי ויעיל, אלא גם להצלחה בבחינות הקורס, המרבות לבחון את היכולת לשלב בין שני התחומים בצורה נכונה.
טיפול בקבצים בפייתון
תוכניות רבות זקוקות ליכולת לקרוא נתונים מקבצים או לכתוב נתונים אליהם, בין אם מדובר בקבצי תצורה, דוחות, נתוני משתמשים או כל מידע אחר. פייתון מספקת ממשק פשוט ויעיל לעבודה עם קבצים.
פתיחה, קריאה וכתיבה לקבצים
הפעולה הראשונה בעבודה עם קובץ היא פתיחתו באמצעות הפונקציה open(), המקבלת נתיב לקובץ ומצב פתיחה. לאחר סיום העבודה, חשוב לסגור את הקובץ כדי לשחרר משאבים ולשמור שינויים.
מצב 'r' (read)
פתיחה לקריאה בלבד. אם הקובץ לא קיים, תתעורר שגיאת FileNotFoundError. מצב ברירת המחדל.
מצב 'w' (write)
פתיחה לכתיבה. אם הקובץ קיים, תוכנו יימחק. אם לא קיים, הוא ייווצר. כותב מההתחלה.
מצב 'a' (append)
פתיחה לכתיבה, אך הכתיבה מתבצעת בסוף הקובץ. אם הקובץ לא קיים, הוא ייווצר.
מצב 'x' (exclusive creation)
פתיחה לכתיבה, אך רק אם הקובץ אינו קיים. אם הקובץ קיים, תתעורר שגיאת FileExistsError.
לצד מצבים אלו, ניתן להוסיף 'b' לעבודה עם קבצים בינאריים (לדוגמה, 'rb', 'wb') או '+' כדי לאפשר גם קריאה וגם כתיבה (לדוגמה, 'r+', 'w+').
ניהול משאבים עם with open()
הדרך המומלצת והבטוחה ביותר לעבוד עם קבצים בפייתון היא באמצעות הצהרת with open(...) as file:. מבנה זה מבטיח שהקובץ ייסגר אוטומטית בסיום הבלוק, גם אם מתרחשת שגיאה בתוכו.
טיפול בשגיאות וחריגות
תוכניות עלולות להיתקל בשגיאות בזמן ריצה עקב קלט לא חוקי, קבצים חסרים, בעיות רשת או באגים בקוד. טיפול בחריגות מאפשר לתוכנית להמשיך לפעול בצורה מבוקרת במקום לקרוס.
מבנה try-except-else-finally
try
הקוד שיש לנסות לבצע. אם מתרחשת חריגה, הביצוע עובר לבלוק except המתאים.
except
מטפל בחריגות ספציפיות (או בכל חריגה). ניתן לציין סוג חריגה (לדוגמה, except FileNotFoundError:).
else
קוד שמתבצע רק אם בלוק try הושלם בהצלחה (כלומר, לא התרחשה שום חריגה).
finally
קוד שמתבצע תמיד, ללא קשר אם התרחשה חריגה או לא. אידיאלי לשחרור משאבים (לדוגמה, סגירת קבצים אם לא השתמשנו ב-with).
חריגות נפוצות
FileNotFoundError: קובץ לא נמצא.IOError: שגיאת קלט/פלט כללית (לדוגמה, בעיות הרשאה).ValueError: ערך לא חוקי (לדוגמה, ניסיון להמיר מחרוזת שאינה מספר למספר).TypeError: פעולה לא חוקית על סוג נתונים מסוים.
שילוב טיפול בקבצים וטיפול בשגיאות
הבחינות בקורס מרבות לשלב בין שני הנושאים, ומצפות מכם לכתוב קוד חזק שמטפל בשגיאות פוטנציאליות בעת עבודה עם קבצים.
with open() ו-try-except: זוהי נקודה קריטית בבחינות. בעוד ש-with open() מבטיח סגירת קובץ, הוא אינו מטפל בשגיאות שעלולות להתרחש לפני פתיחת הקובץ (כמו FileNotFoundError) או שגיאות לוגיות בתוך בלוק ה-with עצמו. שילוב של try-except סביב בלוק ה-with מאפשר לטפל גם בשגיאות אלו, ובכך ליצור קוד עמיד ואמין לחלוטין.דוגמה: ניסיון לקרוא מקובץ שייתכן שאינו קיים, ולטפל בשגיאה אם הוא אכן חסר:
try:
with open("my_data.txt", "r") as f:
content = f.read()
print("תוכן הקובץ:", content)
except FileNotFoundError:
print("שגיאה: הקובץ 'my_data.txt' לא נמצא.")
except IOError as e:
print(f"שגיאת קלט/פלט בעת גישה לקובץ: {e}")
except Exception as e:
print(f"אירעה שגיאה בלתי צפויה: {e}")
else:
print("הקובץ נקרא בהצלחה.")
finally:
print("סיום ניסיון קריאת קובץ.")
שאלות לדיון
- מדוע השימוש ב-
with open(...)עדיף על פני פתיחה וסגירה ידנית של קבצים באמצעותopen()ו-file.close()? - הסבירו את סדר הביצוע של הבלוקים
try,except,elseו-finally, ותנו דוגמה לכל אחד. - כיצד הייתם מטפלים במצב שבו תוכנה מנסה לכתוב לקובץ, אך אין לה הרשאות כתיבה לתיקייה?
- מתי עדיף להשתמש בבלוק
exceptכללי (לדוגמה,except Exception:) ומתי עדיף לציין סוגי חריגות ספציפיים?
נקודות לתשובת מודל
with open(...): מבטיח סגירה אוטומטית של הקובץ גם במקרה של שגיאה בתוך הבלוק, מונע דליפת משאבים ומפשט את הקוד.- סדר ביצוע
try-except-else-finally:try: מבוצע ראשון.- אם אין חריגה:
elseמבוצע, ואזfinally. - אם יש חריגה:
exceptמתאים מבוצע, ואזfinally. finally: מבוצע תמיד, ללא קשר לתוצאה.
- טיפול בהרשאות כתיבה: יש להשתמש בבלוק
try-exceptולצפות לחריגות כמוPermissionError(אוIOErrorכללי יותר). בתוך ה-except, ניתן להציג הודעת שגיאה למשתמש או לנסות נתיב חלופי. exceptכללי מול ספציפי:- ספציפי: עדיף ברוב המקרים. מאפשר לטפל בכל סוג שגיאה באופן ממוקד ושונה, משפר את קריאות הקוד ומקל על ניפוי באגים.
- כללי: יש להשתמש בזהירות רבה, בעיקר במקרים שבהם לא ניתן לצפות את כל סוגי השגיאות, או כ"מלכודת" אחרונה לאחר טיפול בחריגות ספציפיות. עלול להסתיר באגים אמיתיים.