2.27. Читання та запис

Файли знаходяться на диску; Python отримує до них доступ через open(), який повертає файловий об’єкт, методи якого читають та записують байти, що лежать в основі.

2.27.1. open та режими

Перший аргумент – це шлях; другий – режим – короткий рядок, що вказує 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. Використовуйте для зображень, записів зі структурованою упаковкою, мережевих захоплень – всього, де кожен байт важливий і файл не є людиночитабельним.

2.27.6. Перелік та видалення файлів

Модуль os надає операції файлової системи, яких немає у файловому об’єкті:

  • os.listdir() – повертає список імен у директорії.

  • os.remove() – видалити файл.

  • os.rename() – перейменувати файл.

  • os.stat() – метадані файлу (розмір, час зміни, …).

  • os.mkdir() – створити нову директорію.

import os

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

Перехоплюйте OSError навколо цих операцій, коли файл або директорія може бути відсутньою – ці операції є одними з найпоширеніших місць появи винятків у реальних скриптах.