Работа с файлами
Contents
Работа с файлами¶
Функция open, контекстный менеджер with¶
Для работы с файлами существует функция open, которая создаёт файловый объект и наиболее часто используются с двумя параметрами:
f = open(file, mode)
file — путь к файлу (глобальный или относительно текущей директории);
mode — режим, в котором требуется открыть файл. Параметр
file
обязательный, а в качестве параметраmode
передаётся строка символов:
Символ |
Значение |
---|---|
|
Открыть на чтение (по умолчанию) |
|
Открыть на запись (содержимое существующего файла уничтожается) |
|
Создать файл и открыть на запись (ошибка, если файл существует) |
|
Открыть файл на запись (если файл существует, то дозаписывать в конец файла) |
|
Открыть как бинарный файл |
|
Открыть как текстовый файл (по умолчанию) |
|
Открыть на запись и чтение |
По умолчанию функцию open
открывает файл как текстовый для чтения, но указав mode
можно это поменять.
Чтобы продемонстрировать поведение функции open
, рассмотрим пример. Для начала создадим файл средствами python. Сделать это в папке tmp
можно было бы следующими командами.
filename = "./tmp/first_file.txt"
f = open(filename, "w")
Но у такого подхода есть один недостаток: он может не сработать на другой платформе. Тут есть ряд деталей
В
unix-like
системах (Ubuntu
,OSX
) в качестве разделителя каталогов используется символ/
, а вwindows
используется\
;Символ
\
используется python для экранирования символов. Например, комбинация\n
— новая строка и т.п. Чтобы корректно использовать разделитель каталогов\
вwindows
необходимо использовать илиr
строки (rC:\Users\Ivan
) внутри которых\
не используется для экранирования, или экранировать сам символ\
(‘C:\Users\Ivan’);
Поэтому, для работы с путями в файловых системах используется модуль стандартной библиотеки os или pathlib, которые предоставляют платформонезависимый интерфейс для работы с файловыми системами. Подробнее они будут обсуждаться ниже, а пока воспользуемся модулем pathlib
, чтобы задать файл first_file.txt
внутри папки tmp
.
from pathlib import Path
import os
# Используя pathlib
folder = Path("tmp")
filename = folder / "first_file.txt"
print(filename)
# Используя os
filename = os.path.join("tmp", "first_file.txt")
print(filename)
tmp\first_file.txt
tmp\first_file.txt
Как мы видим, создался путь в стиле Windows
. Это произошло, потому-что сборка этих материалов осуществлялась на машине под управлением Windows 10
. Теперь откроем файл на запись и запишем в него три строки.
Note
Так как мы хотим создать файл внутри папки tmp
, то создадим её с помощью метода os.makedirs.
os.makedirs(folder, exist_ok=True)
f = open(filename, "w")
f.write("Первая строка.\n")
f.write("Вторая строка.\n")
f.write("Последняя строка.")
f.close()
По исполнению этой ячейки должен был создаться файл first_file.txt
в папке ./tmp
.
Когда работа с файлом прекращена, следует вызвать метод close()
у файлового объекта. Вообще говоря, этот метод вызовется автоматически при сборке мусора. Однако, если программа упадёт до закрытия файла, то могут произойти неожиданные последствия.
Хорошей практикой является использование ключевого слова with для работы с файлами:
with open(filename, "w") as f:
f.write("Первая строка.\n")
f.write("Вторая строка.\n")
f.write("Последняя строка.")
Преимущество такого подхода заключается в том, что файл закроется автоматически при выходе за пределы блока with ... as ...
или при возникновении исключения.
Прочитаем содержимое только что созданного файла.
with open(filename) as f:
print(f.read())
Первая строка.
Вторая строка.
Последняя строка.
Note
При открытии на запись мы передали строку "w"
, а т.к. открытие по умолчанию осуществляется на чтение, то можно не передавать строку "r"
.
Метод read
считывает содержимое всего файла в строку. Может удобнее быть читать из файла по строкам. Для этого можно рассмотреть три основных подхода:
readline
считывает одну строку файла;readlines
возвращает список строк в файле;использовать итератор файлового объекта;
with open(filename) as f:
print("readline:")
print(f.readline())
print(f.readline())
print(f.readline())
end = f.readline()
print(f"|{end}|")
readline:
Первая строка.
Вторая строка.
Последняя строка.
||
Метод readline
считывает одну строку из файла и передвигает указатель на следующую. Если файл закончился, то считывается пустая строка.
with open(filename) as f:
print("readlines:")
print(f.readlines())
readlines:
['Первая строка.\n', 'Вторая строка.\n', 'Последняя строка.']
readlines
считывает сразу все строки (начиная с текущего указателя) из файла и возвращает список из них.
Tip
Оба этих метода оставляют символы переноса в строке. Строковый метод rstrip позволяет избавиться от них при необходимости.
Самый распространенный подход — использование файлового объекта для итерации по файлу.
with open(filename) as f:
for line in f:
print(repr(line.rstrip()))
'Первая строка.'
'Вторая строка.'
'Последняя строка.'
Модули os, pathlib, glob¶
При работе с файлами возникает необходимость взаимодействия с файловой системой. Чаще всего для этого используются 4 следующих модуля стандартной библиотеки:
Разберем ряд методов из этих модулей.
Текущая директория¶
Во время работы программы есть такое понятие как рабочая (текущая) директория/папка (похоже на pwd
в unix-like
системах). В самом начале исполнения программы рабочей директорией является та директория, из которой был запущен скрипт/ноутбук/сессия интерпретатора. Узнать эту папку в любой момент времени можно командой os.getcwd, а поменять (перейти в другую папку, похоже на cd
в командной строке) можно командой os.chdir (сокращение от change directory
).
При открытии файлов путь к ним можно указывать в абсолютном формате (т.е. начиная с буквы диска в windows
(r"C:\users\user_name\some_file.txt"
)
) или с корневой директории /
в unix-like
системах ("/home/users/user_name/some_file.txt"
)) или относительно текущей папки.
Путь к файлу/папке¶
Из-за того, что разделители каталогов в разных операционных системах разные, то формирования пути рекомендуется использовать os.path.join
или Path
из pathlib
.
Содержимое папки¶
Получить список файлов и папок в директории можно:
методом os.listdir, который по умолчанию возвращает список файлов в текущей директории, но в качестве опционального аргумента принимает путь до папки, содержимое которой необходимо вывести;
методом
glob.glob
из модуляglob
. Этот метод предоставляет доступ к поиску файлов, название которых удовлетворят некоторому шаблону. Например, поиск всех файлов с расширением".txt"
в текущей директории можно выполнить командойglob.glob("*.txt")
.
Проверить, существует ли файл по указанному пути, можно методом os.path.exists.
Создание папок¶
Для создания директорий используются методы
os.mkdir создаёт папку по указанному пути и бросает ошибку, если папка уже существует. Так же бросает ошибку, если по пути нужно создать больше, чем одну папку; Проверить, существует ли уже папка по указанному пути, можно методом os.path.isdir;
os.makedirs делает тоже самое, но может обрабатывать существующие папки (параметр
exist_ok
) и создавать необходимые папки по пути.
Tip
Если нужно создавать временные файлы или папки исключительно на время работы программы или даже меньше, то модуль tempfile предоставляет удобный интерфейс для таких операций.