Программирование и IT

Python: чтение файла

Работа с файлом состоит из трёх шагов: открыть, прочитать или записать, закрыть. Закрытие лучше не делать руками — для этого есть оператор `with`. А главный параметр, про который забывают, — кодировка: без неё один и тот же код на разных машинах читает файл по-разному.

Обновлено
В этой статье

Открыть правильно: оператор with#

with open("notes.txt", encoding="utf-8") as f:
    content = f.read()
print(content)

with закрывает файл сам — и когда блок закончился нормально, и когда внутри
случилось исключение. Ручной вариант f = open(...) / f.close() работает,
но при ошибке между этими строками файл остаётся открытым, а данные записи —
не сброшенными на диск.

Режим задаётся вторым аргументом:

Режим Что делает
r чтение, по умолчанию; файла нет — FileNotFoundError
w запись; существующий файл обнуляется
a дозапись в конец, файл создаётся при отсутствии
x создание; файл уже есть — FileExistsError
rb wb двоичный режим, работа с bytes

Самая дорогая ошибка новичка — открыть для проверки файл в режиме w:
содержимое исчезает в момент открытия, ещё до первой записи.

Три способа прочитать#

with open("notes.txt", encoding="utf-8") as f:
    whole = f.read()          # всё одной строкой

with open("notes.txt", encoding="utf-8") as f:
    lines = f.readlines()     # список строк, с переводами строк внутри

with open("notes.txt", encoding="utf-8") as f:
    for line in f:            # по одной строке, файл любого размера
        print(line.rstrip("\n"))

Третий способ — основной. Файловый объект сам является итератором и отдаёт
строки по одной, не загружая в память весь файл: так читают и сто строк, и
гигабайтный журнал.

Каждая строка приходит вместе с завершающим \n, поэтому print(line) даёт
двойные переносы. Убирают их rstrip("\n") — именно с аргументом, иначе
rstrip() срежет заодно и значимые пробелы в конце строки.

with open("nums.txt", encoding="utf-8") as f:
    total = sum(int(line) for line in f if line.strip())
print(total)

Такое выражение считает сумму чисел из файла, не создавая списка, — приём из
статьи про генераторы.

Запись и дозапись#

with open("out.txt", "w", encoding="utf-8") as f:
    f.write("первая строка\n")
    f.write("вторая строка\n")

with open("out.txt", "a", encoding="utf-8") as f:
    f.write("дописали позже\n")

rows = ["раз", "два", "три"]
with open("rows.txt", "w", encoding="utf-8") as f:
    f.write("\n".join(rows))

write не добавляет перевод строки — его ставят сами. writelines тоже не
добавляет, вопреки названию: он просто пишет элементы подряд. Поэтому для
списка строк удобнее "\n".join(...), как в третьем примере — про сам метод
написано в статье про строки.

Печать умеет писать прямо в файл: print("текст", file=f) — и перевод строки
она ставит сама.

Кодировка#

Без аргумента encoding Python берёт кодировку по умолчанию для системы. На
Linux и macOS это обычно UTF-8, а на Windows исторически может быть
однобайтовая кодовая страница. Один и тот же код тогда читает файл
по-разному: на одной машине текст, на другой — UnicodeDecodeError или
нечитаемые символы.

Правило простое: указывай encoding="utf-8" в каждом вызове open для
текста. Если файл пришёл из старой программы и в UTF-8 не читается, пробуй
encoding="cp1251". Когда встречаются единичные битые байты и терять файл
жалко, помогает errors="replace" — непрочитанные места станут знаком замены
вместо падения.

with open("legacy.txt", encoding="cp1251") as f:
    print(f.read())

Двоичный режим кодировки не имеет вовсе: open(path, "rb") отдаёт bytes, и
аргумент encoding с ним несовместим.

Ошибки и короткая запись через pathlib#

try:
    with open("нет-такого.txt", encoding="utf-8") as f:
        data = f.read()
except FileNotFoundError:
    data = ""
    print("файла нет, работаем с пустыми данными")

FileNotFoundError — нормальная ситуация, её ловят; как устроен перехват,
разобрано в статье про исключения. Рядом
встречаются PermissionError (нет прав) и IsADirectoryError (указали папку).

Для коротких операций в стандартной библиотеке есть pathlib:

from pathlib import Path

p = Path("notes.txt")
p.write_text("привет\n", encoding="utf-8")
print(p.read_text(encoding="utf-8"))   # привет
print(p.exists(), p.suffix, p.stem)    # True .txt notes

Path умеет складывать пути через /: Path("data") / "2026" / "log.txt"
это работает одинаково на всех системах, в отличие от склейки строк со
слэшами.

Практика: создай файл из десяти строк, прочитай его построчно и запиши
в новый файл только строки длиннее пяти символов, добавив в начало каждой
номер. Проверь, что исходный файл не пострадал.

План по этапам

  1. Создать и прочитатьЗаписать три строки в файл в режиме w, затем прочитать его целиком через with.
  2. Построчный переборПройти по файлу циклом for и убрать завершающий перевод строки через rstrip("\n").
  3. ДозаписьОткрыть тот же файл в режиме a, добавить строку и убедиться, что старое содержимое на месте.
  4. Поймать отсутствие файлаОбратиться к несуществующему имени и обработать FileNotFoundError.
  5. Повторить через pathlibСделать то же самое методами Path.read_text и Path.write_text с явной кодировкой.

Начать изучать эту тему у себя

План ляжет в твой репозиторий: отмечай этапы, веди конспект — история изменений покажет, как ты продвинулся.

Начать план

Проверь себя

1.В каком режиме открытия существующий файл обнуляется?

2.Что делает оператор with при работе с файлом?

3.Какое исключение возникнет при open("нет-такого.txt") в режиме r?

4.Файл содержит строки «10», «20», «30». Чему равно sum(int(line) for line in open("nums.txt", encoding="utf-8"))?

Источники

Было полезно?

Ещё темы

Программирование и IT Файл .gitignore В проекте всегда есть файлы, которым в репозитории не место — кэш, папки сборки, настройки редактора, локальные пароли. Список таких файлов держат в .gitignore, и git перестаёт предлагать их к добавлению. Программирование и IT Как изучить Python с нуля Python хорош для первого знакомства с программированием: код читается почти как текст, а стандартная библиотека закрывает большинство бытовых задач. Этот план ведёт от установки интерпретатора до собственных скриптов, покрытых тестами, — примерно за четыре месяца при занятиях около часа в день. Программирование и IT Python: декораторы Декоратор — это функция, которая принимает другую функцию и возвращает новую, с добавленным поведением. Знак `@` перед определением — просто короткая запись присваивания. Если держать это в голове, вся тема разбирается за один вечер. Программирование и IT Python: функции Функция — именованный кусок кода, который принимает значения и возвращает результат. В Python объявление занимает одну строку, но у аргументов есть тонкости: умолчания вычисляются один раз, именованные и позиционные смешиваются по правилам, а без return функция всё равно что-то возвращает. Программирование и IT Python: классы Класс описывает, из каких данных состоит объект и что он умеет делать. Конструктор `__init__` заполняет новый объект, `self` — ссылка на него самого. Ниже — минимальный рабочий класс, разница между атрибутом класса и атрибутом экземпляра и способы сделать код короче. Программирование и IT Python: задачи с решениями Подборка задач по возрастанию сложности — от разворота строки до генератора и декоратора-счётчика. Сначала решай сам и только потом открывай разбор: сравнение своего кода с чужим даёт больше, чем чтение готового. Все решения проверены на Python 3.

Ещё сценарии