Чтобы эффективно управлять крупными объемами данных, целесообразно не использовать списки или словари, а сохранять их в файлах. В языках программирования предусмотрена возможность работы с файлами. В Python файлы рассматриваются как объекты файловых классов. То есть, аналогично типам данных, как список, словарь или целое число, текстовый файл также является типом данных.
Файлы обычно классифицируются как текстовые и бинарные. Текстовые файлы содержат символьные данные и строки, в то время как бинарные – поток байтов. Например, изображения читаются побайтово.
Работа с бинарными файлами может быть более сложной. Обычно для их обработки используют специальные модули Python, такие как pickle или struct. В этом уроке будут разобраны основные методы чтения текстовых файлов и записи в них.
Функция open() – открытие файла
Для открытия файла используется встроенная в Python функция open(). Она обычно принимает один или два аргумента. Первый аргумент – это имя файла или полный путь, если файл исключительно не находится в том же каталоге, что и скрипт. Второй аргумент указывает на режим, в котором файл открывается.
Основные режимы: чтение ('r') и запись ('w'). Открытый в режиме чтения файл недоступен для записи, можно лишь читать данные. В режиме записи добавлять данные возможно, но считать нельзя.
Если файл открыт в режиме 'w', предшествующие данные будут удалены, и файл станет пустым. Чтобы сохранить текущие данные и добавить новые, стоит выбрать режим дозаписи ('a').
При отсутствии файла, режим 'w' создаст новый. Чтобы гарантированно создать новый файл без риска случайного перезаписи, можно использовать режим 'x'. Он создаёт новый файл, а если файл с указанным именем уже существует, будет выброшено исключение.
По умолчанию open() открывает файл в текстовом режиме чтения, если режим не указан. Чтобы открыть файл в бинарном режиме, добавьте к символу режима 'b'. Символ 't' указывает на текстовый режим, но его чаще всего опускают, так как это состояние по умолчанию.
Недопустимо использовать только тип файла, например, open("имя_файла", 'b') выдаст ошибку, даже при чтении. Правильное использование: open("имя_файла", 'rb'). Текстовые файлы можно открыть с командой open("имя_файла"), поскольку режимы 'r' и 't' предполагаются по умолчанию.
Открытие с помощью open() возвращает файл как объект, который нужно либо связать с переменной, чтобы не потерять, либо сразу же прочитать.
Чтение файла
Метод read() позволяет прочитать содержимое файла полностью или частично, по указанному количеству байт. Пусть в файле data.txt находится следующее содержимое:
one - 1 - I two - 2 - II three - 3 - III four - 4 - IV five - 5 - V
Чтение файла:
>>> f1 = open('data.txt') >>> f1.read(10) 'one - 1 - ' >>> f1.read() 'I\ntwo - 2 - II\nthree - 3 - III\nfour - 4 - IV\nfive - 5 - V\n' >>> f1.read() '' >>> type(f1.read()) <class 'str'>
Сначала считываются десять байтов, соответствующие десяти символам. Хотя файл не является бинарным, доступно побайтовое чтение. Последующее вызов read() извлекает оставшийся текст. После этого объект f1 становится пустым.
Заметьте, метод read() возвращает строку, а конец строки как '\n'.
Для построчного чтения файла можно использовать метод readline():
>>> f1 = open('data.txt') >>> f1.readline() 'one - 1 - I\n' >>> f1.readline() 'two - 2 - II\n' >>> f1.readline() 'three - 3 — III\n'
Метод readlines() считывает все строки и формирует их в список:
>>> f1 = open('data.txt') >>> f1.readlines() ['one - 1 - I\n', 'two - 2 - II\n', 'three - 3 - III\n', 'four - 4 - IV\n', 'five - 5 - V\n']
Объект файлового типа является итерируемым, что позволяет извлекать его элементы итерационно. Это означает, что данные можно читать в цикле, игнорируя методы чтения:
>>> f1 = open('data.txt') >>> for i in open('data.txt'): ... print(i) ... one - 1 - I two - 2 - II three - 3 - III four - 4 - IV five - 5 - V >>>
Вывод включает лишние пустые строки. Это происходит из-за того, что функция print() преобразует '\n' в переход на новую строку и добавляет ещё один переход. Можно создать список строк файла без '\n':
>>> nums = [] >>> for i in open('data.txt'): ... nums.append(i[:-1]) ... >>> nums ['one - 1 - I', 'two - 2 - II', 'three - 3 - III', 'four - 4 - IV', 'five - 5 - V']
Переменной i присваивается текущая строка файла. Через оператор среза отбрасывается последний символ, поскольку '\n' — это один символ.
Запись в файл
Методы write() и writelines() используются для записи в файл. Второй метод позволяет передавать в файл структуру данных:
>>> l = ['tree', 'four'] >>> f2 = open('newdata.txt', 'w') >>> f2.write('one') 3 >>> f2.write('two') 4 >>> f2.writelines(l)
Метод write() возвращает количество записанных символов.
Закрытие файла
После завершения работы с файлом важно его закрыть, чтобы освободить ресурсы памяти. Это делается методом close(). Свойство closed файлового объекта помогает узнать закрыто ли файл.
>>> f1.close() >>> f1.closed True >>> f2.closed False
При открытии файла в заголовке цикла (for i in open('fname')
), интерпретатор автоматически закрывает файл после
завершения цикла.
Практическая работа
- Создайте файл nums.txt с несколькими числами, записанными через пробел. Напишите программу, которая посчитает и выведет общую сумму чисел, хранящихся в этом файле.