Tutorial

Использование модуля pathlib для манипуляции путями файловых систем в Python 3

Published on August 19, 2020
Русский
Использование модуля pathlib для манипуляции путями файловых систем в Python 3

Автор выбрал 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)

Если запустить этот код, результат будет выглядеть следующим образом:

Output
ocean/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)

Если запустить этот код, результат будет выглядеть следующим образом:

Output
ocean/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)

Если мы выполним этот код, мы увидим следующие результаты:

Output
ocean/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)

Этот код произведет следующий вывод:

Output
ocean/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)

Если запустить этот код, результат будет выглядеть следующим образом:

Output
ocean/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)

Если запустить его, результат будет выглядеть следующим образом:

Output
ocean/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, возникшее из этого кода, которое будет выглядеть следующим образом:

Output
Traceback (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.

Learn more about our products

About the authors
Default avatar

Author of Intuitive Python

Check out Intuitive Python: Productive Development for Projects that Last

https://pragprog.com/titles/dmpython/intuitive-python/



Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


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!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.