2.27. קריאה וכתיבה

קבצים חיים על הדיסק; Python מגיע אליהם דרך open(), שמחזירה אובייקט קובץ שהמתודות שלו קוראות וכותבות את הבייטים הבסיסיים.

2.27.1. open ומצבים

הארגומנט הראשון הוא הנתיב; השני הוא המצב (mode) – מחרוזת קצרה שאומרת ל-Python כיצד ייעשה שימוש בקובץ:

  • "r" – קריאה (ברירת מחדל). פותח קובץ קיים לקריאה.

  • "w" – כתיבה. יוצר קובץ חדש או מקצר קובץ קיים לריק.

  • "a" – הוספה. פותח קובץ לכתיבה בסופו בלי לקצר.

  • "b" המצורף לכל אחד מהנ“ל ("rb", "wb", "ab") – מצב בינארי. תוכן הקובץ הוא bytes ולא str.

f = open("notes.txt", "r")
text = f.read()
f.close()

2.27.2. השתמשו במנהל הקשר

התבנית שלמעלה מדליפה את ידית הקובץ אם משהו בין open() ל-close זורק חריגה. התיקון הוא פקודת ה-with (ראו מנהלי הקשר):

with open("notes.txt") as f:
    text = f.read()

# f is closed here, even if read() failed

זוהי הצורה הסטנדרטית – כתבו אותה כך בכל פעם.

2.27.3. קריאה

אובייקטי קובץ תומכים במספר סגנונות קריאה:

  • io.IOBase.read() – קוראת את כל הקובץ (או N בייטים) ומחזירה אותו כמחרוזת יחידה (או אובייקט bytes).

  • io.IOBase.readline() – קוראת שורה אחת, כולל ה-"\n" בסופה.

  • איטרציה ישירה על הקובץ מניבה שורות אחת בכל פעם, עם שימוש זיכרון קטן בהרבה מקריאת כל הקובץ בבת אחת.

with open("log.txt") as f:
    for line in f:
        print(line.rstrip())

str.rstrip() מסירה את תו השורה החדשה בסוף לפני ההדפסה כך שהפלט אינו ברווח כפול.

2.27.4. כתיבה

פתחו את הקובץ במצב "w" והשתמשו ב-io.IOBase.write():

with open("out.txt", "w") as f:
    f.write("hello\n")
    f.write("world\n")

io.IOBase.write() אינה מוסיפה שורה חדשה – היא כותבת בדיוק את הבייטים (או התווים, במצב טקסט) שאתם נותנים לה.

2.27.5. טקסט מול בינארי

מצב טקסט (ברירת מחדל, "r" / "w" ללא "b") מפענח בייטים נכנסים ל-str באמצעות קידוד ברירת מחדל, ומקודד str יוצא בחזרה לבייטים. השתמשו בו לתצורה, יומנים, JSON – כל דבר שהוא טקסט.

מצב בינארי ("rb" / "wb") מדלג על שלב הפענוח ומחזיר bytes. השתמשו בו לתמונות, רשומות ארוזות-struct, לכידות רשת – כל דבר שבו כל בייט חשוב והקובץ אינו קריא לאדם.

2.27.6. רשימת קבצים והסרתם

מודול ה-os חושף את פעולות מערכת הקבצים שאינן על אובייקט הקובץ עצמו:

  • os.listdir() – מחזירה רשימת שמות בתיקייה.

  • os.remove() – מחיקת קובץ.

  • os.rename() – שינוי שם של קובץ.

  • os.stat() – מטא-נתוני קובץ (גודל, זמן שינוי, …).

  • os.mkdir() – יצירת תיקייה חדשה.

import os

for name in os.listdir("/"):
    print(name)

תפסו OSError סביב אלה כאשר הקובץ או התיקייה עשויים שלא להיות שם – הפעולה היא אחד המקומות הנפוצים שבהם חריגות צצות בסקריפטים אמיתיים.