Как использовать модуль Pathlib
В этой статье мы на примерах разберем, как использовать модуль Pathlib в Python. Все операционные системы имеют разные правила построения путей к файлам. Например, в Linux для путей используется косая черта (слэш, /), а в Windows — обратная косая черта (обратный слэш, ).
Эта небольшая разница может вызвать ряд проблем, если вы работаете над проектом и хотите, чтобы разработчики могли работать с вашим кодом и в других операционных системах.
К счастью, если вы программируете на Python, модуль Pathlib сделает за вас всю тяжелую работу. Он обеспечит одинаковую работу ваших путей к файлам в разных операционных системах. Кроме того, данный модуль предоставляет функции и операции, которые помогут вам сэкономить время при обработке путей и управлении ими.
Установка
Pathlib поставляется по умолчанию с Python (версии 3.4 и выше). Однако если вы используете версию Python ниже 3.4, у вас не будет доступа к этому модулю.
Как работает Pathlib?
Чтобы понять, как создается базовый путь с помощью Pathlib, давайте рассмотрим пример. Создадим новый файл Python с именем example.py и поместим его в определенный каталог.
Откройте файл и введите следующее содержимое:
import pathlib p = pathlib.Path(__file__) print(p)
В этом примере мы импортируем модуль Pathlib. Затем мы создаем новую переменную с именем p для хранения пути. Здесь мы используем объект Path из Pathlib со встроенной в Python переменной с именем __file__. Эта переменная служит ссылкой на путь к файлу, в котором мы ее пишем (example.py).
Если мы выведем значение p, мы получим путь к файлу, в котором мы сейчас находимся:
/home/rochdikhalid/dev/src/package/example.py
Как показано выше, Pathlib создает путь к этому файлу, помещая конкретный скрипт в объект Path. Pathlib содержит множество объектов, таких как PosixPath() и PurePath(), к которым мы еще вернемся.
Pathlib делит пути файловой системы на два разных класса, которые представляют два типа объектов пути: Pure Path и Concrete Path.
Pure Path предоставляет утилиты для обработки пути к файлу и управления им без выполнения операций записи, в то время как Concrete Path позволяет манипулировать и выполнять операции записи в файл.
Другими словами, Concrete Path является подклассом Pure Path. Он наследует манипуляции от родительского класса и добавляет операции ввода/вывода, которые выполняют системные вызовы.
Английский для программистов
Наш телеграм канал с тестами по английскому языку для программистов. Английский это часть карьеры программиста. Поэтому полезно заняться им уже сейчас
Подробнее ×
Pure Path в Python
Pure Path управляют путем к файлу на вашем компьютере, даже если он принадлежит другой операционной системе.
Например, предположим, что вы работаете в Linux и хотите использовать путь к файлу Windows. Здесь объекты класса Pure path помогут вам заставить путь работать на вашем компьютере. Они сделают это с помощью нескольких базовых операций, таких как создание дочерних путей или доступ к отдельным частям пути.
Однако Pure Path не смогут выполнить некоторые другие операции, такие как создание каталога или файла, потому что на самом деле вы не находитесь в этой операционной системе.
Как использовать Pure Path
Как вы можете видеть на диаграмме выше, Pure Path состоят из трех классов, которые обрабатывают любой путь к файловой системе на вашем компьютере.
PurePath() — это корневой узел, который обеспечивает операции обработки для каждого объекта пути в Pathlib.
Когда вы создаете экземпляр PurePath(), он создает два класса для обработки путей Windows и путей, отличных от Windows. PurePath() создает общий объект пути «agnostic path», независимо от операционной системы, в которой вы работаете.
In [*]: pathlib.PurePath('setup.py') Out[*]: PurePosixPath('setup.py')
PurePath() в приведенном выше примере создает PurePosixPath(), потому что мы предположили, что работаем на машине с Linux. Но если вы создадите его экземпляр в Windows, вы получите что-то вроде PureWindowsPath(‘setup.py’).
PurePosixPath() — это дочерний узел PurePath(), реализованный для путей файловой системы, отличной от Windows.
In [*]: pathlib.PurePosixPath('setup.py') Out[*]: PurePosixPath('setup.py')
Вы не получите никакой ошибки, если создадите экземпляр PurePosixPath() в Windows, потому что этот простой класс не выполняет системных вызовов.
PureWindowsPath() — это дочерний узел PurePath(), реализованный для путей файловой системы Windows.
In [*]: pathlib.PureWindowsPath('setup.py') Out[*]: PureWindowsPath('setup.py')
С PureWindowsPath() дела обстроят так же, как и с PurePosixPath(): поскольку этот класс не выполняет системных вызовов, его создание не вызовет ошибок для других операционных систем.
Свойства PurePath
Каждый подкласс в PurePath() предоставляет следующие свойства:
1. PurePath().parent выводит родительский класс:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').parent Out[*]: PurePosixPath('/src/goo/scripts')
В приведенном выше примере мы используем свойство .parent, чтобы получить путь к логическому родителю main.py.
2. PurePath().parents[] выводит предков пути:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py') p.parents[0] Out[*]: PurePosixPath('/src/goo/scripts') In [*]: p.parents[1] Out[*]: PurePosixPath('/src/goo')
Нужно обязательно указывать индекс в квадратных скобках, как это показано выше. В Python 3.10 и выше вы также можете использовать срезы и отрицательные значения индекса.
3. PurePath().name предоставляет имя последнего компонента вашего пути:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').name Out[*]: 'main.py'
В этом примере последний компонент пути — main.py. Таким образом, свойство .name выводит имя файла main.py.
4. А PurePath().suffix предоставляет расширение файла последнего компонента вашего пути:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').suffix Out[*]: '.py'
Свойство .suffix, в отличие от .name, выводит только расширение файла и исключает его имя.
5. PurePath().stem выводит, наоборот, только имя конечного компонента вашего пути без суффикса:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').stem Out[*]: 'main'
Как видно выше, свойство .stem исключает суффикс конечного компонента main.py и предоставляет только имя файла.
Методы PurePath
Кроме того, каждый подкласс PurePath() предоставляет следующие методы:
1. PurePath().is_absolute() проверяет, является ли ваш путь абсолютным:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py') p.is_absolute() Out[*]: True In [*]: o = pathlib.PurePath('scripts/main.py') o.is_absolute() Out[*]: False
Обратите внимание, что абсолютный путь состоит из корня и имени диска. В этом случае PurePath() не позволяет нам узнать имя диска.
Если вы используете PureWindowsPath(), вы можете представить абсолютный путь, содержащий имя диска, например PureWindowsPath(‘c:/Program Files’).
2. PurePath().is_relative() проверяет, принадлежит ли путь другому заданному пути:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py') p.is_relative_to('/src') Out[*]: True In [*]: p.is_relative_to('/data') Out[*]: False
В этом примере указанный путь /src является частью или принадлежит пути p, в то время как другой указанный путь — /data — вызывает значение False, поскольку он не имеет никакого отношения к пути p.
3. PurePath().joinpath() объединяет путь с заданными аргументами (дочерние пути):
In [*]: p = pathlib.PurePath('/src/goo') p.joinpath('scripts', 'main.py') Out[*]: PurePosixPath('/src/goo/scripts/main.py')
Обратите внимание, что нет необходимости добавлять слэши в указанные вами аргументы, так как метод .joinpath() сделает это за вас.
4. PurePath().match() проверяет, соответствует ли путь заданному шаблону:
In [*]: pathlib.PurePath('/src/goo/scripts/main.py').match('*.py') Out[*]: True In [*]: pathlib.PurePath('/src/goo/scripts/main.py').match('goo/*.py') Out[*]: True In [*]: pathlib.PurePath('src/goo/scripts/main.py').match('/*.py') Out[*]: False
Исходя из приведенных выше примеров, шаблон должен соответствовать пути. Если данный шаблон является абсолютным, путь также должен быть абсолютным.
5. PurePath().with_name() изменяет имя конечного компонента вместе с его суффиксом:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py') p.with_name('app.js') Out[*]: PurePosixPath('/src/goo/scripts/app.js') In [*]: p Out[*]: PurePosixPath('/src/goo/scripts/main.py')
Метод .with_name() не изменяет имя последнего компонента навсегда. Кроме того, если указанный путь не содержит имени, возникает ошибка, как указано в официальной документации.
6. PurePath().with_stem() изменяет только имя конечного компонента пути:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py') p.with_stem('app.py') Out[*]: PurePosixPath('/src/goo/scripts/app.py') In [*]: p Out[*]: PurePosixPath('/src/goo/scripts/main.py')
Это похоже на метод .with_name(), но.with_stem() временно изменяет лишь имя последнего компонента. Кроме того, если указанный путь не содержит имени, произойдет ошибка.
7. PurePath().with_suffix() временно изменяет суффикс или расширение конечного компонента вашего пути:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py') p.with_suffix('.js') Out[*]: PurePosixPath('/src/goo/scripts/main.js')
Если имя данного пути не содержит суффикса, метод .with_suffix() добавит суффикс за вас:
In [*]: p = pathlib.PurePath('/src/goo/scripts/main') p.with_suffix('.py') Out[*]: PurePosixPath('/src/goo/scripts/main.py')
А если мы не включим суффикс и оставим аргумент пустым, текущий суффикс будет удален.
In [*]: p = pathlib.PurePath('/src/goo/scripts/main.py') p.with_suffix('') Out[*]: PurePosixPath('/src/goo/scripts/main')
Некоторые методы, такие как .with_stem() и .is_relative_to(), недавно были добавлены в Python 3.9 и выше. Поэтому, если вы вызовете эти методы с помощью Python 3.8 или ниже, возникнет ошибка.
Concrete Paths в Python
Concrete Paths позволяет обрабатывать, манипулировать и выполнять операции записи над различными путями файловой системы.
Другими словами, этот тип объекта пути помогает нам создать, например, новый файл, новый каталог и выполнять другие операции ввода/вывода, не находясь в этой операционной системе.
Как использовать Concrete Paths
Concrete Paths обрабатывают любой путь к файловой системе и выполняют системные вызовы на вашем компьютере. Эти объекты пути являются дочерними путями PurePath и состоят из трех подклассов, как и PurePath:
1. Path() является дочерним классом PurePath(). Он обеспечивает операции обработки с возможностью выполнения операций записи.
Когда вы создаете экземпляр Path(), он создает два класса для обработки путей Windows и путей, отличных от Windows. Как и PurePath(), Path() также создает общий объект пути «agnostic path», независимо от операционной системы, в которой вы работаете.
In [*]: pathlib.Path('setup.py') Out[*]: PosixPath('setup.py')
Path() в приведенном выше примере создает PosixPath(), потому что мы предполагаем, что работаем на машине с Linux. Но если вы создадите его в Windows, вы получите что-то вроде WindowsPath(‘setup.py’)
2. PosixPath() — это дочерний класс Path() и PurePosixPath(), реализованный для обработки и управления путями файловой системы, отличной от Windows.
In [*]: pathlib.PosixPath('setup.py') Out[*]: PosixPath('setup.py')
Вы получите сообщение об ошибке, если создадите экземпляр PosixPath() на компьютере с Windows, потому что нельзя выполнять системные вызовы, работая в другой операционной системе.
3. WindowsPath() — это дочерний класс Path() и PureWindowsPath(), реализованный для путей файловой системы Windows.
In [*]: pathlib.WindowsPath('setup.py') Out[*]: WindowsPath('setup.py')
Создание WindowsPath(), если вы работаете в другой операционной системе, тоже вызовет ошибку.
Свойства Concrete Paths
Поскольку Concrete Paths является подклассом PurePath, мы можем использовать все свойства PurePath(). Это означает, что мы можем использовать, например, свойство .with_suffix для добавления суффикса к конкретному пути:
In [*]: p = pathlib.Path('/src/goo/scripts/main') p.with_suffix('.py') Out[*]: PosixPath('/src/goo/scripts/main.py')
Или можем проверить, относится ли указанный путь к исходному пути, с помощью .is_relative_to:
In [*]: p = pathlib.Path('/src/goo/scripts/main.py') p.is_relative_to('/src') Out[*]: True
Всегда помните, что Concrete Paths наследуют операции обработки от PurePath и добавляют операции записи, которые выполняют системные вызовы и конфигурации ввода/вывода.
Методы Concrete Paths
Каждый подкласс Path() предоставляет следующие методы для обработки путей и выполнения системных вызовов:
1. Path().itertir() возвращает содержимое каталога. Допустим, у нас есть папка, содержащая следующие файлы:
data population.json density.json temperature.yml stats.md details.txt
Чтобы вернуть содержимое каталога /data, вы можете использовать метод .itertir():
In [*]: p = pathlib.Path('/data') for child in p.iterdir(): print(child) Out[*]: PosixPath('/data/population.json') PosixPath('/data/density.json') PosixPath('/data/temprature.yml') PosixPath('/data/stats.md') PosixPath('/data/details.txt')
Метод .itertir() создает итератор, который случайным образом перечисляет файлы.
2. Path().exists() проверяет, существует ли файл/каталог по текущему пути. Давайте воспользуемся каталогом из предыдущего примера (наш текущий каталог — /data):
In [*]: p = pathlib.Path('density.json').exists() p Out[*]: True
Метод .exists() возвращает True, поскольку данный файл существует в каталоге /data. Метод возвращает False, если файл не существует.
In [*]: p = pathlib.Path('aliens.py').exists() p Out[*]: False
То же самое относится и к каталогам: метод возвращает True, если данный каталог существует, и False, если его нет.
3. Path().mkdir() создает новый каталог по заданному пути:
In [*]: p = pathlib.Path('data') directory = pathlib.Path('data/secrets') directory.exists() Out[*]: False In [*]: directory.mkdir(parents = False, exist_ok = False) directory.exists() Out[*]: True
Согласно официальной документации, метод .mkdir() принимает три аргумента. Мы пока сосредоточимся только на parents и exists_ok.
Оба аргумента имеют значение False по умолчанию. Аргумент parents вызывает ошибку FileNotFound в случае отсутствия родителя, тогда как exists_ok вызывает ошибку FileExists, если данный каталог уже существует.
В приведенном выше примере вы можете установить для аргументов значение True, чтобы игнорировать упомянутые ошибки и обновить каталог.
4. Мы также можем создать новый файл по указанному пути, используя метод Path().touch():
In [*]: file = pathlib.Path('data/secrets/secret_one.md') file.exists() Out[*]: False In [*]: file.touch(exist_ok = False) file.exists() Out[*]: True
Здесь для exists_ok тоже можно установить значение True, чтобы игнорировать ошибку FileExists и обновлять файл.
5. Path().rename() переименовывает файл/каталог по указанному пути. Давайте рассмотрим пример, используя наш каталог /data:
In [*]: p = pathlib.Path('density.json') n = pathlib.Path('density_2100.json') p.rename(n) Out[*]: PosixPath('density_2100.json')
Если вы передадите методу несуществующий файл, он вызовет ошибку FileNotFound. То же самое относится и к каталогам.
6. Path().read_text() возвращает содержимое файла в строковом формате:
In [*]: p = pathlib.Path('info.txt') p.read_text() Out[*]: 'some text added'
Кроме того, вы можете использовать метод write_text() для записи содержимого в файл:
In [*]: p = pathlib.Path('file.txt') p.write_text('we are building an empire') Out[*]: 'we are building an empire'
Обратите внимание, что метод .write_text() был добавлен в Python 3.5 и недавно обновлен в Python 3.10, где получил некоторые дополнительные параметры.
Важный момент
Вы можете спросить себя, зачем использовать пути файловой системы Windows, ведь каждый пакет должен быть совместим и с другими операционными системами.
Вы правы, если цель состоит в том, чтобы сделать путь, не зависящий от ОС. Но иногда мы не можем этого сделать из-за настроек, уникальных для систем Windows или Posix. Некоторые пакеты нацелены на решение проблем, присутствующих только в экосистеме Windows, и Python поддерживает эти юзкейсы в данной библиотеке.
Заключение
Итак, мы познакомились с модулем Pathlib в Python и на примерах разобрали, как его использовать Надеемся, вы поняли, насколько он полезен для обработки и управления путями файловой системы.
В официальной документации вы найдете больше методов и свойств, которые сможете применить к путям вашей файловой системы.
Перевод статьи «Python Path – How to Use the Pathlib Module with Examples».
Английский для программистов
Наш телеграм канал с тестами по английскому языку для программистов. Английский это часть карьеры программиста. Поэтому полезно заняться им уже сейчас
Скачать ×
- 9 views
- 0 Comment