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

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

Введение

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

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

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

python3 files.py

Создать

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

Опции:

r  чтение

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

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

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

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

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

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

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

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.eth1.ru 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.eth1.ru 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.eth1.ru 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.eth1.ru 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.eth1.ru 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.eth1.ru www.heihei.ru

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

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

www.eth1.ru 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.eth1.ru 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.eth1.ru\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.eth1.ru 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 Oct 12 15:21 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

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

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

Article author: Andrei Olegovich

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

Search this site

Subscribe to Telegram channel @aofeed to follow new articles and updates to old ones

Go to channel

@aofeed

Ask a question in the Telegram group

@aofeedchat

Contacts and cooperation:
I recommend our hosting beget.ru
Write to info@urn.su if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: