В прошлой статье мы говорили об использовании модуля os для работы с каталогами в Python. Сегодня пойдёт речь о высокоуровневом Python-модуле pathlib. Читайте далее, чем отличаются os и pathlib, как управление путями зависит от операционной системы, а также что представляет собой работа с папками и файлами с помощью pathlib.
Иерархия pathlib
Архитектура pathlib состоит из чистых путей (pure path), которые имеют только вычислительные операции, но не имеют операций ввода-вывода, и конкретных путей (concrete path), которые наследуются от чистых путей, но также обладают операциями ввода-вывода. Рисунок ниже показывает иерархию наследования. Как можно заметить, левая часть (Posix Path) используется Unix-системами, а правая — MS Windows.
Если вы не знаете какой класс использовать, выбирайте Path. Его экземпляры будут подстраиваться под операционную систему (ОС), и во время выполнения вы получите конкретные экземпляры либо PosixPath, либо WindowsPath.
Чистые пути будут полезны в следующих случаях:
- Требуется управлять каталогами Windows в Unix-системах или наоборот. У вас не получится создать экземпляр WindowsPath в Unix, но можно воспользоваться PureWindowsPath.
- Требуется только управлять путями, не обращаясь к ОС. В этом случае создание экземпляра одного из чистых классов может быть полезным, поскольку у них просто нет операций доступа к ОС.
В дальнейшем мы покажем, как те же самые операции pathlib выполняются в модуле os. Так, pathlib предоставляет высокоуровневый интерфейс, а os — низкоуровенный, поэтому чаще возвращаемым значением является строка (str), а не объекты Path. Прежде чем приступим, импортируем модули в Python:
>>> from pathlib import Path >>> import os
Текущая рабочая директория
Как мы уже говорили в прошлый раз файловая система и Python работают относительно текущей рабочей директории (current working directory). В pathlib для этого имеет метод cwd:
>>> os.getcwd() '/home/user/Templates' >>> pathlib.Path.cwd() PosixPath('/home/user/Templates')
Ещё более короткий и удобный синтаксис вызова текущей директории – это передача в конструктор точку, а две точки укажут на родителя текущей директории:
>>> Path('.') PosixPath('.') # текущая - '/home/user/Templates' >>> Path('..') PosixPath('..') # родитель - '/home/user/'
Создание путей
Разделитель используется для разделения папок в путях файловой системы. В os-модуле его можно посмотреть, вызвав os.sep
. Но здесь возникают трудности, поскольку путь нужно сначала инициализировать в виде строки (str). А если вы забыли, что в Windows используется обратный слэш для деления папок вместо прямого, то код в этом месте придётся менять после вывода ошибки в Python-программе.
С другой стороны, интерфейс Python-модуля pathlib заставляет передавать путь в конструктор объекта Path, который уже сам решит во время выполнения, каким разделителем пользоваться:
>>> os.sep '/' >>> os.path.join('testfolder', 'sub-dir', 'example.txt') 'testfolder/sub-dir/example.txt' >> Path('testfolder', 'sub-dir', 'example.txt') PosixPath('testfolder/sub-dir/example.txt') >>> p = Path('testfolder/sub-dir')
Чтобы добавить новые пути можно использовать слэш /, подобно арифметическому оператору, либо вызвать метод joinpath
, причём соединять также можно и сами объекты Path:
>>> Path('.') / 'tempdir' / 'example.txt' PosixPath('/home/user/Templates/tempdir/example.txt') >>> p = Path('tempdir/examples.txt') >>> Path.('.') / p PosixPath('/home/user/Templates/tempdir/examples.txt') # либо joinpath >>> Path.('.').joinpath('tempdir', 'example.txt') PosixPath('/home/user/Templates/tempdir/example.txt')
Информация о каталоге
В pathlib можно получить информацию о файле или папке, обращаясь к тем или иным атрибутам. Например, name
для извлечения имени файла и его расширения, suffix
для извлечения расширения файла. В Python это выглядит следующим образом:
# Информация о файле >>> p = Path('tempdir/sub-dir/examples.txt') >>> p.name 'examples.txt' # Расширение файла >>> p.suffix '.txt' # То же самое в os: >>> os.path.basename(p) 'examples.txt' >>> os.path.splitext(p)[1] '.txt'
Гуляем по каталогу
У Path есть метод iterdir
, который сгенерирует все папки и файлы указанного пути. Это очень полезно, когда, например, требуется выявить все файлы необходимого формата. Вот так в Python можно найти все текстовые файлы:
>>> p = Path('.') >>> for file in p.iterdir(): ... if file.suffix == '.txt': ... print(file.name) ... example.txt example2.txt
Ещё проще это можно сделать, используя метод glob
, передав нужное расширение:
>>> for path in p.glob('*.txt'): ... print(path) ... example.txt example2.txt
Чтобы пройтись также и по подпапкам в каталоге, можно воспользоваться методом rglob
. В os для этого используется функция walk
, о котором говорили тут. Ниже пример Python для вывода всех путей каталога, а также вывод файлов текстового формата всего каталога:
>>> p = Path('.') >>> list(p.rglob('*')) [PosixPath('example.txt'), PosixPath('sub-dir1'), PosixPath('example2.txt'), PosixPath('sub-dir2'), PosixPath('sub-dir2/example3.txt')] >>> list(p.rglob('*.txt')) [PosixPath('/home/user/Templates/example.txt') PosixPath('/home/user/Templates/example2.txt'), PosixPath('/home/user/Templates/sub-dir2/example3.txt')]
Работа с папками и файлами
Как и os, модуль pathlib даёт возможность создавать, удалять, переименовывать файлы и папки. Причём названия методов практически идентичные:
>>> Path('new-dir').mkdir() # создать папку >>> Path('new-file').touch() # создать файл >>> Path('super-dir').rmdir() # удалить папку >>> Path('example.txt').unlink() # удалить файл >>> Path('new-dir').rename('super-dir') # переименовать файл или папку PosixPath('super-dir')
Кроме того, содержимое файла Path можно прочитать и записать. Ниже показан пример с записью и последующим чтением файла в Python.
>>> p = Path('exapmle.txt') >>> p.write_text('Hello, python-school') >>> p.read_text() 'Hello, python-school'
os или pathlib: что же всё-таки выбрать
После расcмотрения примеров возникает вопрос: каким Python-модулем пользоваться. Модуль os, помимо прочего, предоставляет множество функций для работы с процессами, пользователями, группами, окружением среды в Unix-системах. Но если вам требуется только интерфейс взаимодействия с файловой системой, стоит использовать pathlib, который будет отталкиваться от вашей ОС. При этом вам не потребуется помнить какой используется разделить в Windows или Unix-системах. Модуль pathlib прост в освоении, поскольку имеет простой синтаксис: нужно просто инициализировать объект Path, а дальше смотреть доступные методы. Кроме того, как уже говорилось в самом начале, многие функции os поддерживают объект Path в качестве аргумента, поэтому можно будет перейти от os к pathlib.
Еще больше подробностей о работе с файловой системой с помощью модуля pathlib на практических примерах реальных Data Science проектов вы узнаете на наших курсах по Python в лицензированном учебном центре обучения и повышения квалификации IT-специалистов в Москве.