Как открыть файл в Python: чтение и запись через with open()

Файл в Python открывают функцией open() внутри with: так он закроется сам, даже если в коде случится ошибка.

Разобрали режимы r, w, a и x, четыре способа чтения, запись с переносами строк, пути через pathlib и ошибку кодировки, из-за которой вместо русских букв появляются непонятные символы.

Статью написал:
Ваня Буявец, продюсер, основатель Checkroi
Ваня Буявец
Основатель Checkroi, продюсер, эксперт в выборе онлайн-курсов
Все 2994 статьи автора Подписаться на Телеграм-канал
Одобрено экспертом:
Наташа Буявец, основатель Checkroi, эксперт по онлайн-курсам
Наташа Буявец
Основательница Checkroi, продюсер Youtube-каналов, эксперт по онлайн-курсам
Все 3648 экспертных мнений Подписаться на Телеграм-канал
Обложка: Как открыть файл в Python: чтение и запись через with open()

Чтобы открыть файл в Python, вызовите встроенную функцию open() внутри конструкции with: with open("notes.txt", encoding="utf-8") as f:. Дальше f.read() вернёт весь текст строкой, а после выхода из блока with Python сам закроет файл. По умолчанию файл открывается на чтение, для записи нужен второй аргумент "w", для дописывания в конец "a".

Ниже разберём режимы, все способы чтения и записи, кодировки и пути. Если Python ещё не стоит, начните с инструкции как скачать и установить Python. А если вы искали, как открыть сам файл с расширением .py и запустить его, это другая задача: она разобрана в статье как создать и запустить файл Python в VS Code.

CheckroiCheckroiПодборка курсов по Python568 курсов • 51 школаСравните цены, школы, программу и найдите выгодные предложения по обучениюСравнить→

Как открыть файл в Python за четыре шага

Рой открывает папку с текстовым файлом и читает строки на экране

Возьмём простую задачу: сохранить список дел в текстовый файл и прочитать его обратно. В питоне этот код работает одинаково на Windows, macOS и Linux.

  1. Положите файл рядом со скриптом или создайте его из кода, как в примере ниже.
  2. Откройте файл через with open(...) as f. Первым аргументом идёт путь, вторым режим, а кодировку задают именованным параметром encoding.
  3. Прочитайте содержимое методом read() или пройдите по строкам циклом for.
  4. Работайте с данными после блока with: файл к этому моменту уже закрыт, а текст лежит в переменной.
with open("notes.txt", "w", encoding="utf-8") as f:
    f.write("Купить хлеб\nПозвонить маме\nОплатить интернет\n")

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

print(text)
print(f.closed)

Вывод:

Купить хлеб
Позвонить маме
Оплатить интернет

True

Последняя строка True показывает, что файл закрыт без вызова f.close(). Без with закрывать его пришлось бы руками, и при ошибке посередине скрипта файл так и остался бы открытым. Поэтому во всех примерах дальше открываем файлы только через with.

Режимы открытия файла

Три лотка с листами: чтение, перезапись и дописывание в конец

Режим передают вторым аргументом строкой. Буквы складываются: "rb" означает чтение в двоичном виде, "a+" дописывание с возможностью чтения. Полная таблица есть в официальной документации функции open(), на практике хватает шести вариантов.

Режим Что делает Если файла нет Если файл есть
"r" чтение текста, режим по умолчанию FileNotFoundError читает с начала
"w" запись создаёт пустой стирает содержимое сразу при открытии
"a" дописывание в конец создаёт пустой пишет после старого текста
"x" только создание нового файла создаёт FileExistsError
"r+" чтение и запись без очистки FileNotFoundError позиция в начале файла
"rb", "wb" двоичный режим для картинок, архивов, PDF как у r и w как у r и w

Главная ловушка таблицы во второй строке. Режим "w" очищает файл в момент открытия, ещё до первой записи. Открыли не тот файл на запись и закрыли, и данные пропали.

Двоичный режим отдаёт не строку, а байты, и кодировка в нём не указывается:

with open("photo.bin", "wb") as f:
    f.write(bytes([0x89, 0x50, 0x4E, 0x47]))

with open("photo.bin", "rb") as f:
    data = f.read()

print(data, type(data).__name__, len(data))
b'\x89PNG' bytes 4
Канал основателя Checkroi Вани Буявца3 700 человек читают мой Телеграм-канал про нейросетиСобрал промпты для Claude Code и ChatGPT, разборы ИИ-инструментов и лайфхаки по продвижению бизнеса в одном местеПрисоединиться

Как прочитать файл: read, readline, readlines и цикл for

У открытого файла четыре способа достать текст. Они отличаются тем, сколько данных попадает в память за раз и в каком виде.

read(): весь файл одной строкой

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

readline(): по одной строке за вызов

with open("notes.txt", encoding="utf-8") as f:
    print(repr(f.readline()))
    print(repr(f.readline()))
'Купить хлеб\n'
'Позвонить маме\n'

Обратите внимание на \n в конце: символ переноса остаётся частью строки. Отсюда пустые строки между записями, когда такой текст печатают через print().

readlines(): список всех строк

with open("notes.txt", encoding="utf-8") as f:
    print(f.readlines())
['Купить хлеб\n', 'Позвонить маме\n', 'Оплатить интернет\n']

Переносы на месте и здесь. Чтобы получить чистый список, читайте файл целиком и режьте методом splitlines(): f.read().splitlines() даст ['Купить хлеб', 'Позвонить маме', 'Оплатить интернет']. Другие способы разбить текст собраны в разборе как преобразовать строку в список.

Цикл for для больших файлов

with open("notes.txt", encoding="utf-8") as f:
    for line in f:
        print(line.strip())
Купить хлеб
Позвонить маме
Оплатить интернет

Файловый объект сам отдаёт строки по одной, поэтому цикл работает на файле любого размера: в памяти лежит только текущая строка. Метод strip() срезает перенос и пробелы по краям, остальные методы есть в шпаргалке по методам строк.

Как записать данные в файл

Для записи есть три инструмента: write(), writelines() и обычный print() с параметром file. Первые два не добавляют перенос строки сами, и это частая причина склеенного текста.

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

print(open("log.txt", encoding="utf-8").read())
перваявторая

Решение: ставить \n в конце каждой строки или писать через print(), который добавляет перенос сам.

with open("log.txt", "w", encoding="utf-8") as f:
    f.write("первая\n")
    f.writelines(["вторая\n", "третья\n"])
    print("четвёртая", file=f)

with open("log.txt", "a", encoding="utf-8") as f:
    f.write("пятая\n")

После этого в log.txt пять строк по порядку. Второй блок открыл файл в режиме "a", поэтому строка «пятая» встала в конец, а старый текст остался. Так обычно ведут логи: каждый запуск скрипта дописывает свои события, ничего не затирая. Зачем вообще нужны такие файлы и как их читать, рассказано в статье про лог-файлы.

Два файла можно открыть в одном with через запятую. Удобно, когда читаете из одного и пишете в другой:

with open("notes.txt", encoding="utf-8") as src, open("copy.txt", "w", encoding="utf-8") as dst:
    for line in src:
        dst.write(line.upper())
КУПИТЬ ХЛЕБ
ПОЗВОНИТЬ МАМЕ
ОПЛАТИТЬ ИНТЕРНЕТ

Табличные и структурированные данные удобнее писать не построчно, а готовыми модулями: для таблиц есть csv (разобран в статье формат CSV и как прочитать его в Python), для вложенных структур json. Про сам формат есть отдельный материал что такое JSON.

Кодировка: почему вместо русских букв значки

Рой подбирает ключ к замку, и непонятные символы превращаются в буквы

С русским текстом бывает так: файл открывается без ошибок, но вместо «Привет, мир» на экране вот что:

Привет, мир

Так выглядит текст, сохранённый в UTF-8 и прочитанный в кодировке Windows cp1251. В обратную сторону, когда файл в cp1251 открывают как UTF-8, Python падает с ошибкой:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcf in position 0: invalid continuation byte

Откуда берётся путаница. До версии 3.14 включительно Python без параметра encoding брал кодировку системы. На macOS и Linux это UTF-8, а на русской Windows обычно cp1251. В Python 3.15, который вышел 9 октября 2026 года, кодировкой по умолчанию стала UTF-8 на всех системах: изменение описано в PEP 686 и в списке новинок Python 3.15. Старое поведение можно вернуть переменной окружения PYTHONUTF8=0.

Решение одно для всех версий: всегда указывайте encoding="utf-8" явно. Тогда скрипт ведёт себя одинаково на вашем ноутбуке, у коллеги на Windows и на сервере.

  • Файл пришёл из старой программы для Windows и вместо букв показывает непонятные символы? Откройте его с encoding="cp1251".
  • Первая строка начинается с невидимого \ufeff. Значит, у файла метка BOM, её ставят некоторые программы при сохранении в UTF-8. Читайте его с encoding="utf-8-sig", метка исчезнет.
  • Чтобы прочитать файл с битыми байтами и не упасть, добавьте errors="replace": сломанные символы заменятся на �, остальной текст останется.

Путь к файлу и модуль pathlib

Относительный путь вроде "data/notes.txt" Python считает от текущей рабочей папки, а не от папки со скриптом. Запустили python app.py изнутри папки проекта, и файл нашёлся. Запустили тот же скрипт из соседней папки или кнопкой в редакторе с другой рабочей папкой, и получили FileNotFoundError, хотя файл лежит на месте.

Надёжнее строить путь от расположения самого скрипта модулем pathlib:

from pathlib import Path

BASE = Path(__file__).parent
path = BASE / "data" / "notes.txt"

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

Такой код находит файл, откуда бы его ни запустили. У объекта Path есть и короткие методы для простых случаев: path.read_text(encoding="utf-8") читает файл целиком, path.write_text(...) записывает, path.exists() проверяет, есть ли файл. Описание всех методов — в документации pathlib.

Как создать папку, проверить, переименовать и удалить файл

Функция open() умеет создавать только файлы. Если в пути есть папка, которой ещё нет, будет FileNotFoundError. Папку создают заранее, остальные операции с файлами тоже удобно делать через Path:

from pathlib import Path

folder = Path("reports") / "2026"
folder.mkdir(parents=True, exist_ok=True)

report = folder / "october.txt"
print(report.exists())
report.write_text("итоги месяца\n", encoding="utf-8")
print(report.exists())

new_name = report.rename(folder / "october-final.txt")
print([p.name for p in folder.iterdir()])

new_name.unlink()
print(list(folder.iterdir()))
False
True
['october-final.txt']
[]

Параметр parents=True создаёт всю цепочку папок, exist_ok=True не даёт упасть, если папка уже есть. Метод unlink() удаляет файл без корзины, вернуть его не получится.

Пути Windows и обратный слеш

В обычной строке обратный слеш начинает спецсимвол, и путь "C:\new\table.txt" молча превращается в строку с переносом и табуляцией. Проверка показывает 14 символов вместо 16. Пишите такие пути с префиксом r или через прямые слеши:

r"C:\new\table.txt"
"C:/new/table.txt"

Python на Windows понимает оба варианта.

Ваня БуявецКанал основателя Checkroi Вани БуявцаЗабирайте промпты и обучение по нейросетям в моём Телеграм-каналеБольше 3 700 человек уже применяют Claude Code, ChatGPT и другие нейросети в работе, учёбе, бизнесе и жизниПерейти в канал

Частые ошибки и что с ними делать

Сообщения ниже скопированы из запуска на Python 3.14, в таком виде их увидите и вы.

Ошибка Причина Решение
FileNotFoundError: [Errno 2] No such file or directory опечатка в имени или относительный путь считается от другой рабочей папки путь через Path(__file__).parent, проверка path.exists()
UnicodeDecodeError: 'utf-8' codec can't decode byte файл сохранён в другой кодировке encoding="cp1251" или errors="replace"
io.UnsupportedOperation: not writable файл открыт на чтение, а код пытается писать открыть в режиме "a", "w" или "r+"
ValueError: I/O operation on closed file. обращение к файлу после выхода из with читать внутри блока, данные сохранять в переменную
IsADirectoryError или PermissionError в путь попала папка вместо файла, нет прав или файл занят другой программой проверить путь, закрыть файл в Excel или редакторе
файл внезапно пустой его открыли в режиме "w" для дописывания режим "a", для защиты от перезаписи "x"

Ошибку отсутствующего файла удобно ловить в try, чтобы скрипт не падал, а сообщал, что делать:

try:
    with open("settings.txt", encoding="utf-8") as f:
        settings = f.read()
except FileNotFoundError:
    settings = ""
    print("Файл настроек не найден, беру значения по умолчанию")

Ещё одна мелочь, на которой путаются при чтении с середины файла. У текстового файла метод tell() возвращает не номер символа. В нашем списке дел после первой строки он показал 22, хотя в строке «Купить хлеб» вместе с переносом 12 символов. В документации модуля io это значение названо непрозрачным числом, которое можно передать в seek(), чтобы вернуться к той же позиции. Номер символа по нему не посчитать, пример выше это показывает.

Когда работа с файлами освоена, её удобно закрепить на практике: пройдитесь по задачам по Python для начинающих и оберните повторяющийся код чтения в собственную функцию.

Где освоить Python системно

Работа с файлами входит в базовую часть программ по Python. Следом обычно идут модули csv и json, работа с папками, обработка исключений и автоматизация рутины: переименовать сотню файлов, собрать отчёт из выгрузок, разобрать логи. Если хочется пройти этот путь по программе с проверкой заданий, ниже курсы из нашего каталога. Сравнить их по цене, длительности и формату можно на странице курсов по Python, а понять, куда такие навыки ведут дальше, поможет обзор профессии Python-разработчика.

КурсШколаСтоимость со скидкойВ рассрочкуДлитель­ностьОбзор курса от Checkroi
Профессия «Python-разработчик»
Перейти на сайт курса
SkillboxSkillbox157 335 ₽5987 ₽/мес.10 месяцевОбзор курса
Fullstack-разработчик на Python
Перейти на сайт курса
НетологияНетология137 011 ₽7125 ₽/мес.21 месяцОбзор курса
ДО Профессия Python-разработчик
Перейти на сайт курса
GeekBrainsGeekBrains149 001 ₽3167 ₽/мес.10 месяцевОбзор курса
Автоматизированное тестирование на Python
Перейти на сайт курса
SkillboxSkillbox118 666 ₽4108 ₽/мес.9 месяцевОбзор курса
Программирование на Python ПРО
Перейти на сайт курса
SkillboxSkillbox119 600 ₽ - 17 месяцевОбзор курса

Больше программ — в полном каталоге курсов по Python

Часто задаваемые вопросы

Как открыть файл в Python для чтения?

Через функцию open() внутри with: with open("file.txt", encoding="utf-8") as f: text = f.read(). Режим чтения стоит по умолчанию, указывать "r" не обязательно. После выхода из блока with файл закроется сам.

Чем отличаются режимы w и a?

Режим "w" стирает содержимое файла в момент открытия и пишет с чистого листа. Режим "a" дописывает новые данные в конец и старый текст не трогает. Оба создают файл, если его нет.

Почему вместо русских букв в файле непонятные символы?

Файл сохранён в одной кодировке, а прочитан в другой: чаще всего UTF-8 и Windows-кодировка cp1251. Указывайте encoding="utf-8" явно при каждом open(), а файлы из старых программ для Windows открывайте с encoding="cp1251".

Как прочитать файл построчно в Python?

Пройдите по файлу циклом: for line in f:. Файловый объект отдаёт строки по одной, поэтому способ подходит и для очень больших файлов. Перенос в конце строки убирает line.strip().

Нужно ли закрывать файл, если открывал через with?

Нет. Конструкция with закрывает файл сама, когда код выходит из блока, даже если внутри случилась ошибка. Вызывать close() вручную нужно только при открытии без with.

Почему Python не находит файл, который лежит рядом со скриптом?

Относительный путь считается от текущей рабочей папки, а не от папки со скриптом. Стройте путь так: Path(__file__).parent / "file.txt" из модуля pathlib, тогда файл найдётся при любом способе запуска.

Читайте Checkroi первым в Google
Добавьте Checkroi в избранные источники — и наши разборы курсов и обзоры школ будут показываться выше в вашей выдаче Google.
Оставить комментарий
0 комментариев
Форма комментария

Оставьте комментарий

Напишите, что думаете. Нам важно ваше мнение!