Основы работы с файлами в Python

Содержание
Введение
Создать
open(): Открыть
close(): Закрыть
with: Менеджер контекста
Очистить файл
read(): чтение файла
readline() и readlines(): построчное чтение
Копировать файл
Запись в файл
Дописать к файлу
Похожие статьи

Введение

В этой статье вы узнаете как организовать работать с файлами в Python 3.

Создайте файл files.py и копируйте туда код из примеров.

Запустить файл можно командой

python3 files.py

Создать

Создать файл можно командой open

Опции:

r  чтение

rb чтение в бинарном режиме

rt чтение в текстовом режиме

только запись.

wb запись в бинарном режиме

wt запись в текстовом режиме

w+ запись и чтение

запись в конец файла - сохранит данные, которые были в файле

b - это селектор бинарного режима

t - это селектор текстового режима

Любая опция с w перезапишет существующий файл - будьте внимательны!

Пример:

f = open("log.txt","w+")

Кодировка

docs.python.org/3/library/codecs.html#standard-encodings

import sys print(sys.getdefaultencoding())

utf-8

Открыть файл

Синтаксис:

open(path_to_file, mode, encoding)

По умолчанию используется кодировка utf-8

Чтобы открыть файл для чтения выполните

f = open("log.txt","r")

Если файл log.txt не существует, он не будет создан

raceback (most recent call last): File "files.py", line 1, in <module> f = open('log.txt', 'r') FileNotFoundError: [Errno 2] No such file or directory: 'log.txt'

Закрыть файл

Чтобы закрыть файл выполните

f.close()

Менеджер контекста

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

Как только вы выйдете из блока в котором открыт файл - он автоматически закроется

with open('text.txt', 'r') as f: pass print(f.closed)

True

С помощью функции type() легко убедиться, что объект, который получается в результате использования with имеет тип _io.TextIOWrapper

Для полноты картины, изучим доступные методы и атрибуты, с помощью dir()

with open('text.txt', 'r') as f: print(type(f)) print(dir(f))

<class '_io.TextIOWrapper'> ['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines']

Так как у объекта есть метод next() по нему удобно итерировать.

with open('text.txt', 'r') as f: print(next(f)) print(next(f)) print(next(f)) print(next(f))

topbicycle.ru heihei.ru eth1.ru Traceback (most recent call last): File "/mnt/c/Users/Andrei/open_ex.py", line 5, in print(next(f)) ^^^^^^^ StopIteration

next() работает до тех пор, пока элементы не закончатся и затем поднимает StopIteration исключение.

Будем рассматривать примеры работы с файлами как с использованием менеджера контекста так и без него.

read(): чтение файла

Получать данные из файла можно с помощью read()

В неё можно передавать аргумент типа int и тогда будет возвращено соответсвующее количество байт содераждания файла.

Прочитать содержимое файла

with open('sites.md', 'r') as f: f_contents = f.read() print(f_contents)

www.urn.su www.heihei.ru www.topbicycle.ru

Рассмотрим файл sites.md который состоит из одной строки

topbicycle.ruheihei.rueth1.ru

>>> f = open('sites.md', mode='rt', encoding='utf-8') >>> f.read(3)

'top'

>>> f.read(7)

'bicycle'

>>> f.read(3)

'.ru'

Чтобы получить всё что осталось в файл нужно вызвать read() без аргументов.

>>> f.read()

'heihei.rueth1.ru'

Если вызвать read() ещё раз, вернётся пустая строка

>>> f.read()

''

В данный момент указатель стоит на конце файла, но его можно переместить с помощью seek()

Прочитать определённое количество символов

with open('sites.md', 'r') as f: f_contents = f.read(20) print(f_contents)

www.urn.su www.heihe

Если выполнять эту команду последовательно - будут прочитаны следующие символы

with open('sites.md', 'r') as f: f_contents = f.read(20) print(f_contents, end = '') f_contents = f.read(20) print(f_contents, end = '')

www.urn.su www.heihei.ru www.topbicycle.

Цикл для произвольного количества символов .read

with open('sites.md', 'r') as f: size_to_read = 10 f_contents = f.read(size_to_read) while len(f_contents) > 0: print(f_contents, end = '') f_contents = f.read(size_to_read)

www.urn.su www.heihei.ru www.topbicycle.ru

Выражение f_contents = f.read(size_to_read) нужно для того, чтобы когда файл закончится и f.read(size_to_read) станет нулем len(f_contents) тоже станет нулем и цикл завершится

Очистить файл

>>> f = open('sites.md', mode='w', encoding='utf-8') >>> f.write('')

0

>>> f.close() >>> exit()

readline(): построчное чтение

Метод readline() выводит содержимое построчно.

А метод readlines() выводит все строки в виде списка

Рассмотрим файл sites.md который состоит из трёх строк

topbicycle.ru heihei.ru eth1.ru

>>> f = open('sites.md', mode='rt', encoding='utf-8') >>> f.readline()

'www.topbicycle.ru\n'

>>> f.readline()

'www.heihei.ru\n'

>>> f.readline()

'eth1.ru'

Когда строки закончатся readline() будет возвращать не ошибку, а просто пустую строку

>>> f.readline()

''

>>> type(f.readline())

<class 'str'>

Если нужно снова читать сначала пригодится метод seek() про которой можно прочитать в статье «Дополнительные приёмы работы с файлами»

>>> f.seek(0)

0

>>> f.readline()

'www.topbicycle.ru\n'

>>> f.close()

Строки по одной с помощью readline() в скрипте

with open('sites.md', 'r') as f: f_contents = f.readline() print(f_contents) f_contents = f.readline() print(f_contents)

www.urn.su www.heihei.ru

Убрать переходы на новую строку можно с помощью end=''

with open('sites.md', 'r') as f: f_contents = f.readline() print(f_contents, end = '') f_contents = f.readline() print(f_contents, end = '')

www.urn.su www.heihei.ru

Цикл для построчного вывода без использования readline()

with open('sites.md', 'r') as f: for line in f: print(line, end = '')

www.urn.su www.heihei.ru www.topbicycle.ru

В качестве альтернативы можно использовать sys.stdout.write()

Про передачу аргументов из терминала вы можете прочитать в статье sys.argv[]

# files.py import sys f = open(sys.argv[1], mode='rt', encoding='utf-8') for line in f: sys.stdout.write(line) f.close()

python files.py sites.md

www.urn.su www.heihei.ru www.topbicycle.ru

readlines()

Метод readlines() выводит все строки в виде списка

>>> f.readlines()

['www.topbicycle.ru\n', 'www.heihei.ru\n', 'eth1.ru']

>>> f.close()

Все строки с символом перехода на новую строку - readlines

with open('sites.md', 'r') as f: f_contents = f.readlines() print(f_contents)

['www.urn.su\n', 'www.heihei.ru\n', 'www.topbicycle.ru\n']

Имя файла

Пример программы, которая выводит на экран имя файла и режим, в котором он открыт

f = open('log.txt', 'r') print(f.name) print(f.mode) f.close()

Если файл log.txt существует, то в терминале вы увидите

log.txt
r

Копирование файлов

Текстовые файлы

Их можно копировать построчно

with open('sites.md', 'r') as rf: with open('sites_copy.txt', 'w') as wf: for line in rf: wf.write(line)

cat sites_copy.txt

www.urn.su www.heihei.ru www.topbicycle.ru

Изображения

Их тоже можно копировать построчно, но открывать и записывать нужно в побитовом режиме. То есть нужно добавлять опцию b

Скачайте изображение велосипеда с сайта TopBicycle.ru или возьмите любую другую картинку

wget https://topbicycle.ru/b/img/stels_pilot_950_MD_26.jpg
ls

stels_pilot_950_MD_26.jpg

with open('stels_pilot_950_MD_26.jpg', 'rb') as rf: with open('stels_pilot_950_MD_26_copy.jpg', 'wb') as wf: for line in rf: wf.write(line)

python3 files.py
ls

stels_pilot_950_MD_26.jpg stels_pilot_950_MD_26_copy.jpg

Более правильным подходом считается копирование не в построчном режиме а частями с фиксированным размером

with open('stels_pilot_950_MD_26.jpg', 'rb') as rf: with open('stels_pilot_950_MD_26_copy.jpg', 'wb') as wf: chunk_size = 4096 rf_chunk = rf.read(chunk_size) while len(rf_chunk) > 0: wf.write(rf_chunk) rf_chunk = rf.read(chunk_size)

Записать файл

Чтобы очистить файл от старого содержимого и записать в него новое используется опция w (write)

with open('log.txt', 'w') as f: f.write("some text")

Рассмотрим запись в файл в интерактивном режиме и без менеджера контекста

>>> f = open('sites.md', 'w') >>> f.write("topbicycle.ru")

13

>>> f.write("heihei.ru")

9

13 и 9 это число байт переданное в файл

>>> f.close() >>> exit() cat sites.md

cat sites.md www.topbicycle.ru www.heihei.ru eth1.ruwww.aviasales.ru www.booking.comwww.tutu.ru www.velodrive.ruwww.velosklad.ru%

topbicycle.ruheihei.ru

ls -l

-rw-r--r-- 1 andrei users 26 Apr 16 07:16 sites.md

Конечный размер файла будет зависеть от опецарионной системы.

В Windows и Linux разные переносы строк, поэтому когда Python применяет свой универсальный перенос строки количество байт может увеличится на 1 а может остаться прежним.

write() возвращает количество байт, переданных в файл, а не фактический размер записанных данных.

Дописать в файл

Если нужно добавить новые данные к предыдущему содержимому без удаления - используется опция a (append)

with open('log.txt', 'a') as f: f.write("some text")

Рассмотрим пример добавления данных в файл sites.md с помощью метода writelines()

www.topbicycle.ru www.heihei.ru www.eth1.ru

>>> f = open('sites.md', mode='at', encoding='utf-8') >>> f.writelines(['www.aviasales.ru\n', 'www.booking.com', 'www.tutu.ru\n', 'www.velodrive.ru', 'www.velosklad.ru']) >>> f.close() >>> exit()

cat sites.md

www.topbicycle.ru www.heihei.ru eth1.ruwww.aviasales.ru www.booking.comwww.tutu.ru www.velodrive.ruwww.velosklad.ru

Видно, что переносы строк появились только там, где из указали вручную.

Если нужно добавить данные не в конец файла, а в определённое место - изучите пример в статье «Продвинутые приёмы работы с файлами»

Похожие статьи
Работа с файлами в Python
Python
Продвинутые приёмы
glob: Работа с несколькими файлами
shutil: Работа с несколькими файлами
os
pathlib
Скачать файл по сети
psutil: cистемные ресурсы
Обучение программированию на Python