Главная / Блог / Работа с файлами в Python

Работа с файлами в Python

Работа с файлами в Python

Smartiqa Article
  • Дата: 15 октября 2020
  • Автор: Михаил Макарик
Следить за результатами выполнения скрипта в консоли информативно, но не очень весело. Более того, после закрытия терминала весь итог работы кода исчезает. А хочется сохранить всё это куда-то на диск, чтобы потом в любое время рассмотреть повнимательнее. Да и простая задача «работать с файлами» может возникнуть в любое время.

В языке Python для этого предусмотрена встроенная функция open(). Она дает возможность чтения и записи файлов. Об этом ниже.

1. Начало работы

В качестве примера работы с файлами на ПК мы будем использовать war_and_peace.txt (начало романа Л. Н. Толстого «Война и мир»), который разместим в папке скрипта.
В общем виде для открытия файла функцией open() требуется указать либо его расположение относительно текущей директории либо задав абсолютный путь.
Пример – Интерактивный режим

>>> file = open('war_and_peace.txt') 
>>> file.read(50) 
†Eh bien, mon prince. Gênes et Lucques ne s 
>>> file.read() 
Тут выведется оставшаяся часть текста... 
>>> file.read() 
Получим пустую строку 
>>> file.close() 
Рассмотрим подробнее проделанные операции.

1. Мы открыли файл 'war_and_peace.txt' и присвоили его переменной file.

2. Далее мы вывели на печать первые 50 символов объекта. Если в метод read() не передать аргумент, то выведется весь файл. Если вы следом еще раз попытаетесь прочитать файл целиком и вывести на печать, то получите пустую строку (так как file.read() является итератором).
Обратите внимание на сам текст: в нем угадываются французские слова и непонятные кракозябры (к слову, у вас могут отобразиться совсем другие символы). Вывод: с кодировкой беда. Так как мы ее не задали явно, определилась та, которая задана системно. В приведенном выше примере функция open() открыла роман в кодировке cp1251. Но, у самого файла она другая – utf-8.

3. В конце мы закрыли файловый объект, чтобы он не занимал место в памяти.

Нам повезло, что до момента закрытия файла не случилось ошибки, иначе он бы так и остался открытым и занимал некоторый объем памяти.

Читайте также

2. Чтение файла целиком

Чтобы случайно не забыть закрыть файл, функция open() может открываться при помощи контекстного менеджера. Лучше пользоваться всегда таким способом как рекомендуемым разработчиками.

Попытаемся еще раз открыть файл, указав кодировку, режим (на чтение обозначается буквой r).
Пример – Интерактивный режим

>>> with open('war_and_peace.txt', 'r', encoding='utf-8') as file:
           txt = file.read()
>>> txt[:50]
\ufeff— Eh bien, mon prince. Gênes et Lucques ne sont p
>>> txt[:50]
\ufeff— Eh bien, mon prince. Gênes et Lucques ne sont p
В данном случае код вне контекстного менеджера выполняется после закрытия файлового объекта и очистки памяти (даже если бы возникла ошибка).
Переменная txt имеет тип строка. В ней сохранились не только буквы и знаки препинания, но и все скрытые символы (перевод на новую строку, отступы и т.п.). Так как эта переменная хранит строку, то мы к ней можем обращаться любое количество раз.

Существует второй способ чтения файла целиком: через метод readlines(). Он возвращает список строк. Строки идентифицируются по символу '\n'.
Пример – Интерактивный режим

>>> with open('war_and_peace.txt', 'r', encoding='utf-8') as file:
           txt = file.readlines()
>>> txt[0]
"\ufeff— Eh bien, mon prince. Gênes et Lucques ne sont plus que des apanages, des поместья, de la famille Buonaparte. Non, je vous préviens que si vous ne me dites pas que nous avons la guerre, si vous vous permettez encore de pallier toutes les infamies, toutes les atrocités de cet Antichrist (ma parole, j'y crois) — je ne vous connais plus, vous n'êtes plus mon ami, vous n'êtes plus мой верный раб, comme vous dites 1. Ну, здравствуйте, здравствуйте. Je vois que je vous fais peur 2, садитесь и рассказывайте.\n"

Здесь мы вывели на печать первую строку файла.

Итак, теперь текст отображается правильно. Но, имеется еще один неприятный момент, на который не каждый обратит внимание. Наш файл – достаточно мал по объему. Поэтому мы оправданно присвоили всё его содержимое одной переменной. В случае огромных объектов (например, HD-фильм или база данных на сотню миллионов пользователей) это чревато переполнением памяти и возникновением ошибок.

3. Чтение файла частями

Python запись в файл
К счастью, файловый объект может читаться построчно при помощи readline(). Следовательно, мы можем посмотреть каждую строку тяжеловесного файла и проделать над ней какие-то операции.

Выведем на печать первые 50 символов двух первых строк.
Пример – Интерактивный режим

>>> with open('war_and_peace.txt', 'r', encoding='utf8') as file:
           first_line = file.readline()
           second_line = file.readline()
>>> first_line[:50]
\ufeff— Eh bien, mon prince. Gênes et Lucques ne sont p
>>> second_line[:50]
Так говорила в июле 1805 года известная Анна Павло

Такой способ удобен, если нам не нужен весь файл, а лишь его часть. Главный минус – мы можем не знать, сколько строк в файле. А так как readline() не выдает ошибки при окончании текста, то будет просто возвращать пустые.

Если методу readline() передать числовой аргумент, то он посчитает окончанием строки это количество символов.

Чтение по строкам можно провести обычной итерацией в цикле по файловому объекту. Это может понадобиться, если нам требуется провести какие-то преобразования в каждой строке, но нужно прекратить их по окончании файла.
Пример – IDE

with open('war_and_peace.txt', 'r', encoding='utf8') as file:
    for line in file:
        print(line[:15].lower())

Результат выполнения

— eh bien, mon
так говорила в 
«si vous n'avez
— dieu, quelle 
он говорил на т
— avant tout di
— как можно быт
— а праздник ан
— я думала, что
— ежели бы знал
— ne me tourmen
— как вам сказа
князь василий г
быть энтузиастк
В примере выше мы прошлись по всем строкам текста и вывели на печать первые 15 символов каждой строки в нижнем регистре.

4. Запись в файл

Python чтение из файла
Функция open() позволяет не только читать файлы, но и записывать. Для этого требуется сменить режим на w и использовать метод write(). К слову, этот метод принимает только строку в качестве аргумента. Запишем в файл четные числа от 2 до 19 (каждое число – в отдельную строку).
Пример – Интерактивный режим

>>> with open('even.txt', 'w', encoding='utf8') as file:
           for num in range(2, 20, 2):
                file.write(str(num))
В результате появится текстовый файл с четными числами. Но записаны они очень неудобно – в одну строку без пробелов: 24681012141618. Чтобы исправить положение, помимо записи самой строки требуется внести еще и символ окончания строки \n.
Пример – Интерактивный режим

>>> with open('even.txt', 'w', encoding='utf8') as file:
           for num in range(2, 20, 2):
                file.write(str(num) + '\n')
Вот теперь файл выглядит так, как мы запланировали.

Такой способ, конечно, не всегда удобен. Некоторые предпочитают пользоваться другим вариантом записи текста в файл – через привычную функцию print().
Повторим задачу с ее использованием.
Пример – Интерактивный режим

>>> with open('even.txt', 'w', encoding='utf8') as file:
           for num in range(2, 20, 2):
                print(num, file=file)
По умолчанию функция print() выводит информацию (в большинстве случаев текстовую) в поток STDOUT на устройство отображения (монитор). В нашем случае мы его перенаправляем на файловый объект(поток) file.

Используя методику записи в файл нужно понимать, что если файла нет – то он создается, если же он есть, то все его содержимое удаляется и перезаписывается. А, вдруг, вы забыли переименовать документ и случайно переписали его содержимое? Мало приятного.
Избежать такой беды можно использованием режима x.
Пример – Интерактивный режим

>>> with open('even.txt', 'x', encoding='utf8') as file:
           for num in range(2, 20, 2):
                print(num, file=file)

При исполнении кода возникнет ошибка FileExistsError, говорящая о том, что такой файл уже имеется на диске. Поэтому либо создавайте документ с другим наименованием, либо удаляйте старый.

5. Дозапись в файл

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

Так как выше мы уже имеем файл с четными числами до 18, дополним его четными числами до 100 включительно.
Пример – Интерактивный режим

>>> with open('even.txt', 'x', encoding='utf8') as file:
           for num in range(2, 20, 2):
                print(num, file=file)

В документе even.txt теперь имеются все четные числа от 2 до 100.
В статье приведены базовые основы работы с файлами Python на примере функции open(). Она намного сложнее, имеет дополнительные режимы, позволяет взаимодействовать не только с текстовыми документами формата txt, но и любыми другими типами данных (картинками, медиафайлами, excel-таблицами, html-страницами и т.д.).
15 ОКТЯБРЯ / 2020
Как вам материал?

Читайте также