Лекция № 7. Работа с файлами

Хорошевич Павел Александрович

Обработка файлов в Python

Виды файлов

Файлы можно разбить на два вида:

  • Plaintext (текстовые) файлы – содержат информацию, которая понятна человеку;

  • Бинарные файлы – файлы, открыв которые в текстовом редакторе, человек не сможет понять содержимого (исполняемые файлы, изображения, документы и др.).

В заданиях будем использовать только текстовые файлы.

Чтение файла

Чтобы открыть файл используется функция open(<путь>, <режим доступа>).

Эта функция возвращает файловый объект, который будет связан с файлом в файловой системе.

<путь> - это строка с расположением файла, <режим доступа> - строка с режимом в котором мы открываем файл:

  • чтение "r"

  • запись "w".

В следующем коде переменная file_obj будет содержать ссылку на файл с именем verse.txt, открытый для чтения:

script.py
# параметр encoding указывает на кодировку открываемого файла
file_obj = open("verse.txt", "r", encoding="utf-8")

Файл verse.txt должен находиться в той же папке, что и Python-скрипт. Папка из которой запускается скрипт считается для него текущим рабочим каталогом.

graph TD
    folder["📁 Скрипты<br>(текущий рабочий каталог)"]
    script([🐍 script.py])
    file([📋verse.txt])

    folder-->script
    folder-->file
Рисунок 1

После использования, файл нужно закрыть методом close():

file_obj.close()

Если этого не сделать, операционная система будет считать, что файл ещё занят и не даст открыть его другим программам.

Для чтения содержимого текстового файла используются следующие методы файлового объекта:

Методы чтения содержимого файла
Метод Назначение
<файл>.read() Возвращает всё содержимое файла в одной строке (str).
<файл>.readline() Читает следующую строку файла и возвращает её (str).
<файл>.readlines() Возвращает список (list) строк файла.

Пример

Используем все три метода для чтения содержимого следующего файла:

verse.txt
У лукоморья дуб зелёный;
Златая цепь на дубе том:
И днём и ночью кот учёный
Всё ходит по цепи кругом;
Идёт направо — песнь заводит,
Налево — сказку говорит.

Прочитаем всё содержимое файла в виде одной строки:

file_obj = open("verse.txt", "r")
text = file_obj.read() # чтение файла целиком
print(text)
file_obj.close()

Прочитаем файл построчно:

file_obj = open("verse.txt", "r")

line = file_obj.readline() # читаем первую строку
print(line)
line = file_obj.readline() # читаем вторую строку
print(line)

file_obj.close()

Управляющие последовательности

В файле, чтобы обозначить конец строки ставится управляющая последовательность \n - перенос строки.

Функция print() не выводит управляющие символы а интерпретирует их значение.

Запишем все строки в список:

file_obj = open("verse.txt", "r")

lines_list = file_obj.readlines() # список строк
print(lines_list[0:2]) # выведем первые два элемента списка

file_obj.close()

Запись в файл

Для записи в текстовый файл используется метод write(). Файл должен быть открыть для записи, по этому в функции open() второй аргумент будет равен "w" (от англ. write).

output = open("sq_numbers.txt", "w")

for number in range(1, 13):
    square = number * number
    output.write(str(square))
    
output.close()

После запуска скрипта мы увидим в файле такой текст:

149162536496481100121144

Метод write() не добавляет перенос на новую строку. Нужно самостоятельно добавить управляющий символ \n к записываемой строке:

output.write(str(square) + "\n")

Только после этого в файле будут находится значения, записанные с новой строки.

Режим "a" открывает файл для дозаписи в конец файла.

Безопасное открытие файла

С помощью инструкции with можно автоматически закрывать файл после использования:

with <файловый объект> as <имя>:
    <блок инструкций>

Запишем решение задачи с записью квадратов чисел с помощью инструкции with:

with open("sq_numbers.txt", "w") as output:
    for number in range(1, 13):
        square = number * number
        output.write(str(square) + "\n")

После выполнения инструкций внутри with, файл output будет закрыт автоматически.

Пример

Дан список групп и даты проведения зачёта по дисциплине “Методы алгоритмизации и программирование”. В файле шаблон.txt находится текст сообщения, на основе которого нужно создать текст письма для старост групп. Сообщение для каждой группы сохраните в файле. Имя файла [номер группы].txt.

Относительный и абсолютный путь к файлу

Как открыть в скрипте файл data.txt, который находится в другом каталоге?

  • абсолютный путь в котором указывается полная последовательность каталогов начиная с корневого: C:\Проекты\Данные\data.txt

  • относительный путь: ..\Проекты\Данные\data.txt.
    С помощью ..\ поднимаемся на один уровень выше, относительно текущего рабочего каталога.

Чтобы в скрипте work.py открыть файл val.csv запишем следующий относительный путь: ..\..\val.csv.

graph TD
    folderC[📁 C:\]
    scriptCSV([📋val.csv])
    file1([📋exp.txt])
    file2([📋data.txt])
    script3([📋temp.txt])
    foto([🖼️cat.jpg])

    scriptsF["📁 Скрипты<br>(<strong>текущий рабочий каталог</strong>)"]
    dataF["📁 Данные"]
    projF["📁 Проекты"]
    
    script2([🐍 work.py])

    folderC---scriptCSV
    projF---scriptsF
    folderC---projF
    projF---dataF

    scriptsF---script2
    scriptsF---script3

    dataF---file1
    dataF---file2
    dataF---foto
Рисунок 2

Модуль pathlib

Импорт модуля

Модуль pathlib предназначен для унифицированного указания пути к файлам и каталогам на различных операционных системах.

from pathlib import Path

Текущий рабочий каталог

Метод Path.cwd() возвращает объект Path, представляющий текущий рабочий каталог программы.

from pathlib import Path

current_dir = Path.cwd()
print(f"Текущий каталог: {current_dir}")

Домашний каталог пользователя

Метод Path.home() возвращает путь к домашней директории текущего пользователя.

from pathlib import Path

home = Path.home()
print(f"Домашний каталог: {home}")

Path.home() работает кросс-платформенно и автоматически определяет правильный путь для разных операционных систем.

Поиск файлов

Метод glob() позволяет находить файлы по шаблону в указанном каталоге.

  • *.txt : все файлы с расширением .txt (report.txt, notes.txt)

  • data?.csv : файлы с одним символом после “data” (data1.csv, dataA.csv)

  • * : все файлы и папки (любые имена)

* - любое количество произвольных символов, ? - один любой символ.

Пример использования

from pathlib import Path

current = Path.cwd()

# Найти все текстовые файлы в текущем каталоге
txt_files = list(current.glob("*.txt"))
print(f"Найдено файлов: {len(txt_files)}")

# Перебрать результаты в цикле
for file in txt_files:
    print(file)

Рекурсивный поиск: rglob()

Метод rglob() выполняет поиск во всех подкаталогах.

from pathlib import Path

current = Path.cwd()

# Найти все .py файлы в текущем каталоге и подкаталогах
python_files = list(current.rglob("*.py"))

for file in python_files:
    print(file)

Атрибуты объекта Path

from pathlib import Path

p = Path("C:/Users/Student/sam01.py")

print(p.exists())  # существует ли путь
print(p.is_file()) # True, если это файл
print(p.is_dir())  # True, если это каталог

Компоненты пути

Компоненты пути

Методы pathlib.Path

Метод/Атрибут Назначение Возвращает
Path.cwd() Текущий рабочий каталог Path
Path.home() Домашняя директория пользователя Path
glob(pattern) Поиск по шаблону (не рекурсивно) генератор Path
rglob(pattern) Рекурсивный поиск по шаблону генератор Path
exists() Проверка существования пути bool
is_file() / is_dir() Тип объекта bool
name / stem / suffix Части имени файла str
parent Родительский каталог Path