Как было отмечено в предыдущей статье, связанной с чтением данных из файлов, каждому программисту на Python необходимо знать про обработку файлов. Это важнейшая часть языка Python, для этого не нужно загружать никаких дополнительных модулей.
Основы записи файлов в Python
Общие методы для работы с файлами: open()
, чтобы открыть файл, seek()
, чтобы установить текущую позицию файла на заданное смещение, и close()
, чтобы закрыть файловый объект, когда вы закончите его использовать. Метод open()
возвращает ссылку на файл, представляющий файловый объект, чтобы получить доступ к чтению, записи или добавлению.
Запись в файл требует несколько решений — имя файла, куда записывать данные, и режим доступа к файлу. Доступны два режима: запись в новый файл (и перезапись любых существующих данных) и добавление данных в конец уже существующего файла. Соответствующие сокращения — “w” и “a”, их нужно определить перед открытием файла.
В этой статье мы объясним, как записывать данные в файл построчно, как список строк, и как добавлять данные к концу файла.
Запись одной строки в файл
Первый пример похож на запись файлов в двух популярных языках программирования C и C++, что вы увидите в листинге 1. Процесс довольно прямолинеен. Сначала мы открываем файл, используя метод open()
для записи, пишем одиночную строку текста в файл с помощью метода write()
, а затем закрываем файл с помощью метода close()
. Имейте в виду, что из-за способа, которым мы открыли файл “helloworld.txt”, он либо будет создан, если его не существовало, либо полностью перезаписан.
filehandle = open('helloworld.txt', 'w') filehandle.write('Hello, world!n') filehandle.close()
Листинг 1
Весь процесс можно сократить, применив выражение with
. Листинг 2 показывает, как это сделать. Как уже сказано ранее, из-за способа, которым мы открыли файл “helloworld.txt”, он либо будет создан, если его не существовало, либо полностью перезаписан.
with open('helloworld.txt', 'w') as filehandle: filehandle.write('Hello, world!n')
Листинг 2
Запись списка строк в файл
В реальности файл содержит не одну строку, а гораздо больше. Поэтому содержимое файла хранится в списке, представляющем файловый буфер. Чтобы записать файл целиком, мы воспользуемся методом writelines()
. Листинг 3 даёт вам пример.
filehandle = open("helloworld.txt", "w") filebuffer = ["a first line of text", "a second line of text", "a third line"] filehandle.writelines(filebuffer) filehandle.close()
Листинг 3
Запуск программы на Python показан в листинге 3. Используя команду cat
, мы можем видеть, что файл “helloworld.txt” имеет следующее содержимое:
$ cat helloworld.txt a first line of texta second line of texta third line
Листинг 4
Это присходит потому, что метод writelines()
не добавляет автоматически разделители строк, когда пишет файл. Листинг 5 показывает, как этого достичь, записывая каждую строку текста отдельно и добавляя разделитель “n”. Генератор каждой строки заменён на строку с разделителем. Также вы можете сформулировать это с помощью выражения with
.
with open('helloworld.txt', 'w') as filehandle: filebuffer = ["a line of text", "another line of text", "a third line"] filehandle.writelines("%sn" % line for line in filebuffer)
Листинг 5
Теперь выходной файл “helloworld.txt” выглядит нужным образом, как показано в листинге 6:
$ cat helloworld.txt a first line of text a second line of text a third line
Листинг 6
Что любопытно, есть способ перенаправить вывод в Python, чтобы печатать данные в файл. Listing 7 показывает, как это сделать в Python 2.x.
# определим имя выходного файла filename = "helloworld.txt" # определим содержимое filecontent = ["Hello, world", "a second line", "and a third line"] with open(filename, 'w') as filehandle: # перенаправим вывод в файловый поток for line in filecontent: print >>filehandle, line
Листинг 7
В новейших версиях Python такой код больше не работает. Чтобы сделать подобное, мы должны использовать модуль sys
. Он позволяет получить доступ к стандартному потоку вывода UNIX через sys.stdout
, sys.stdin
и sys.stderr
. В таком случае мы сохраняем исходное значение потока вывода sys.stdout
(строка 8 в коде ниже), передаём его обработчику выходного файла, (строка 15), печатаем данные как обычно (строка 18), и наконец возвращаем исходное значение выходного потока sys.stdout
(line 21). Листинг 8 содержит пример кода.
# импортируем модуль sys import sys # определим имя выходного файла filename = "helloworld.txt" # сохраним поток stdout original = sys.stdout # определим содержимое filecontent = ["Hello, world", "a second line", "and a third line"] with open(filename, 'w') as filehandle: # устанавливает новое значение выходного потока sys.stdout = filehandle for line in filecontent: print(line) # возвращаем исходное значение выходного потока sys.stdout = original
Листинг 8
Это не обязательно лучшая практика, но она даёт нам другие варианты для записи строк в файл.
Добавление данных в конец файла
До сих пор мы сохраняли данные в новых файлах или полностью перезаписывали существующие. Но что, если мы хотим добавить данные в конец имеющегося файла? В таком случае нам нужно изменить режим доступа на ‘a’ вместо ‘w’. Листинг 9 показывает, как с этим работать. А листинг 10 делает то же самое, но используя выражение with
.
filehandle = open('helloworld.txt','a') filehandle.write('n' + 'Hello, world!n') filehandle.close()
Листинг 9
with open('helloworld.txt', 'a') as filehandle: filehandle.write('n' + 'Hello, world!n')
Листинг 10
С прежним файлом helloworld.txt запуск этого кода даст следующий результат:
$ cat helloworld.txt Hello, world a second line and a third line Hello, world!
Вывод
Запись простых текстовых данных в файлы, как и добавление данных в существующие файлы, столь же просты, как чтение из файлов в Python. Как только файл закрывается после записи или добавления данных, Python запускает вызов синхронизации. В итоге изменённый файл немедленно записывается на диск.