Автор выбрал COVID-19 Relief Fund для получения пожертвования в рамках программы Write for DOnations.
Python 3 включает модуль pathlib
для манипуляции путями файловых систем независимо от операционной системы. pathlib
похож на модуль os.path
, но pathlib
предлагает более развитый и удобный интерфейс по сравнению с os.path
.
Мы можем идентифицировать файлы на компьютере с помощью иерархических путей. Например, мы можем идентифицировать файл wave.txt
на компьютере с помощью этого пути: /Users/sammy/ocean/wave.txt
. Операционные системы представляют пути несколько по-разному. Windows может представлять путь к файлу wave.txt
как C:\Users\sammy\ocean\wave.txt
.
Модуль pathlib
может быть полезен, если в программе Python вы создаете или перемещаете файлы в файловой системе, указывая все файлы в файловой системе, совпадающие с данным расширением или шаблоном, или создаете пути файла, соответствующие файловой системе на основе наборов неформатированных строк. Хотя вы можете использовать другие инструменты, например модуль os.path
, для выполнения большей части этих задач, модуль pathlib
позволяет выполнять эти операции с большей степенью читаемости и минимальным количеством кодов.
В этом обучающем модуле мы рассмотрим некоторые способы использования модуля pathlib
для представления и манипуляции путями файловых систем.
Чтобы получить максимум знаний из этого обучающего модуля, рекомендуется иметь небольшое представление о программировании на Python 3. Дополнительную информацию можно найти в следующих обучающих руководствах:
Path
Модуль pathlib
предоставляет несколько классов, но одним из наиболее важных является класс Path
. Экземпляры класса Path
представляют путь к файлу или каталогу в файловой системе вашего компьютера.
Например, следующий код инстанциирует экземпляр Path
, который представляет часть пути к файлу wave.txt
:
from pathlib import Path
wave = Path("ocean", "wave.txt")
print(wave)
Если запустить этот код, результат будет выглядеть следующим образом:
Outputocean/wave.txt
from pathlib import Path
делает класс Path
доступным для нашей программы. Затем Path("ocean", "wave.txt")
инстанциирует новый экземпляр Path
. Вывод отображает, что Python добавил соответствующий разделитель оперативной системы /
между двумя заданными нами компонентами пути "ocean"
и "wave.txt"
.
Примечание. В зависимости от операционной системы вывод может немного отличаться от примеров, приведенных в данном руководстве. Если вы работаете в Windows, например, ваш вывод для этого первого примера может выглядеть как ocean\wave.txt
.
В настоящее время объект Path
, назначенный на переменную wave
, содержит относительный путь. Другими словами, ocean/wave.txt
может существовать в нескольких местах в нашей файловой системе. В качестве примера он может существовать в /Users/user_1/ocean/wave.txt
или /Users/user_2/research/ocean/wave.txt
, но мы не указали к какому из них конкретно мы обращаемся. Абсолютный путь, напротив, однозначно четко указывает на расположение в файловой системе.
Вы можете использовать Path.home()
для получения абсолютного пути к домашнему каталогу текущего пользователя:
home = Path.home()
wave_absolute = Path(home, "ocean", "wave.txt")
print(home)
print(wave_absolute)
Если запустить этот код, результат будет выглядеть приблизительно следующим образом:
Output/Users/sammy
/Users/sammy/ocean/wave.txt
Примечание. Как упоминалось ранее, вывод будет зависеть от операционной системы. Ваш домашний каталог также будет отличаться от /Users/sammy
.
Path.home()
возвращает экземпляр Path
с абсолютным путем в домашний каталог текущего пользователя. Затем мы передадим этот экземпляр Path
и строки "ocean"
и "wave.txt"
в другой конструктор Path
, чтобы создать абсолютный путь к файлу wave.txt
. Вывод показывает, что первая строка — это домашний каталог, а вторая строка — домашний каталог плюс ocean/wave.txt
.
Этот пример также иллюстрирует важную функцию класса Path
: конструктор Path
принимает обе строки и ранее существовавшие объекты Path
.
Давайте более детально рассмотрим поддержку строк и объектов Path
в конструкторе Path
:
shark = Path(Path.home(), "ocean", "animals", Path("fish", "shark.txt"))
print(shark)
Если запустить этот код Python, результат будет выглядеть следующим образом:
Output/Users/sammy/ocean/animals/fish/shark.txt
shark
— это Path
к файлу, который мы создали с помощью объектов Path
(Path.home()
и Path("fish", "shark.txt")
и строк "ocean"
и "animals"
). Конструктор Path
интеллектуально обрабатывает оба типа объектов и аккуратно соединяет их с помощью соответствующего разделителя операционной системы, в данном случае /
.
Теперь, когда мы узнали, как создать экземпляры Path
, давайте рассмотрим, как можно использовать эти экземпляры для доступа к информации о файле.
Мы можем использовать атрибуты name
и suffix
для доступа к именам и расширениям файлов:
wave = Path("ocean", "wave.txt")
print(wave)
print(wave.name)
print(wave.suffix)
Запустив этот код, мы получим вывод, аналогичный следующему:
Output/Users/sammy/ocean/wave.txt
wave.txt
.txt
Этот вывод показывает, что имя файла в конце нашего пути — wave.txt
, а расширение файла — .txt
.
Экземпляры Path
также предлагают функцию with_name
, позволяющую беспрепятственно создавать новый объект Path
с другим именем:
wave = Path("ocean", "wave.txt")
tides = wave.with_name("tides.txt")
print(wave)
print(tides)
Если запустить его, результат будет выглядеть следующим образом:
ocean/wave.txt
ocean/tides.txt
Код сначала создает экземпляр Path
, указывающий на файл с именем wave.txt
. Затем мы вызовем метод with_name
в wave
, чтобы вернуть второй экземпляр Path
, указывающий на новый файл с именем tides.txt
. Часть каталога ocean/
остается неизмененной и оставляет финальный путь в виде ocean/tides.txt
Иногда полезно получить доступ к каталогам, содержащим определенный путь. Давайте рассмотрим пример:
shark = Path("ocean", "animals", "fish", "shark.txt")
print(shark)
print(shark.parent)
Если запустить этот код, результат будет выглядеть следующим образом:
Outputocean/animals/fish/shark.txt
ocean/animals/fish
Атрибут parent
в экземпляре Path
возвращает ближайшего предшественника пути данного файла. В этом случае он возвращает каталог с файлом shark.txt
: ocean/animals/fish
.
Мы можем получать доступ к атрибуту parent
несколько раз в строке, чтобы пройти вверх по корневому дереву данного файла:
shark = Path("ocean", "animals", "fish", "shark.txt")
print(shark)
print(shark.parent.parent)
Если мы выполним этот код, мы увидим следующие результаты:
Outputocean/animals/fish/shark.txt
ocean/animals
Вывод будет похож на предыдущий вывод, но теперь мы перешли на уровень выше, получив доступ к .parent
во второй раз. Два каталога от shark.txt
— это каталог ocean/animals
.
Также можно использовать класс Path
для списка файлов с помощью метода glob
.
Допустим, у нас есть структура каталога, которая выглядит следующим образом:
└── ocean
├── animals
│ └── fish
│ └── shark.txt
├── tides.txt
└── wave.txt
Каталог ocean
содержит файлы tides.txt
и wave.txt
. У нас есть файл с именем shark.txt
, вложенный в каталог ocean
, каталог animals
и каталог fish
: ocean/animals/fish
.
Чтобы перечислить все файлы .txt
в каталоге ocean
, можно сказать:
for txt_path in Path("ocean").glob("*.txt"):
print(txt_path)
Этот код произведет следующий вывод:
Outputocean/wave.txt
ocean/tides.txt
Шаблон поиска "*.txt"
находит все файлы, заканчивающиеся на .txt
. Поскольку пример кода выполняет этот поиск в каталоге ocean
, он возвращает два файла .txt
в каталоге ocean
: wave.txt
и tides.txt
.
Примечание. Если вы хотите дублировать выводы, указанные в данном примере, вам потребуется имитировать структуру каталога, изображенную здесь, на компьютере.
Также мы можем использовать метод glob
рекурсивно. Чтобы перечислить все файлы .txt
в каталоге ocean
и все его подкаталоги, мы можем сказать:
for txt_path in Path("ocean").glob("**/*.txt"):
print(txt_path)
Если запустить этот код, результат будет выглядеть следующим образом:
Outputocean/wave.txt
ocean/tides.txt
ocean/animals/fish/shark.txt
Часть **
шаблона поиска будет соответствовать этому каталогу и всем каталогам под ним рекурсивно. Поэтому в выводе у нас будут не только файлы wave.txt
и tides.txt
, но также мы получим файл shark.txt
, вложенный в ocean/animals/fish
.
Мы можем использовать метод Path.relative_to
для вычисления путей, относящихся друг к другу. Метод relative_to
полезен, если, например, вы хотите получить часть длинного пути файла.
Рассмотрите следующий код:
shark = Path("ocean", "animals", "fish", "shark.txt")
below_ocean = shark.relative_to(Path("ocean"))
below_animals = shark.relative_to(Path("ocean", "animals"))
print(shark)
print(below_ocean)
print(below_animals)
Если запустить его, результат будет выглядеть следующим образом:
Outputocean/animals/fish/shark.txt
animals/fish/shark.txt
fish/shark.txt
Метод relative_to
возвращает новый объект Path
, относящийся к данному аргументу. В нашем примере мы вычислим Path
к shark.txt
, относящийся к каталогу ocean
, а затем относящийся к обоим каталогам ocean
и animals
.
Если relative_to
не сможет вычислить ответ, поскольку мы даем ему не связанный путь, он выдаст ValueError
:
shark = Path("ocean", "animals", "fish", "shark.txt")
shark.relative_to(Path("unrelated", "path"))
Мы получим исключение ValueError
, возникшее из этого кода, которое будет выглядеть следующим образом:
OutputTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/Python3.8/pathlib.py", line 899, in relative_to
raise ValueError("{!r} does not start with {!r}"
ValueError: 'ocean/animals/fish/shark.txt' does not start with 'unrelated/path'
unrelated/path
не является частью ocean/animals/fish/shark.txt
, поэтому Python не сможет вычислить относительный путь.
Модуль pathlib
— это мощная часть стандартной библиотеки Python, которая позволяет нам быстро манипулировать путями файловых систем в любой операционной системе. В этом обучающем модуле мы научились использовать некоторые ключевые утилиты pathlib
для доступа к атрибутам файла, спискам файлов с помощью шаблонов поиска и переходить к родительским файлам и каталогам.
Модуль pathlib
представляет дополнительные классы и утилиты, которые мы не охватили в данном руководстве. После получения базового уровня вы можете использовать документацию модуля pathlib
для получения дополнительной информации о других имеющихся классов и утилитах.
Если вас интересуют другие библиотеки Python, ознакомьтесь со следующими обучающими модулями:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!