Язык программирования Python

Управление путями к файлам с помощью pathlib

Управление путями к файлам с помощью Python – это целая история!

Python отлично подходит для создания программ, управляющих файлами и папками. Лично у меня на компьютере каждый день выполняется добрый десяток скриптов для различных задач систематизации и организации операционной системы.

Исторически мы использовали такие модули, как os, glob или shutil для выполнения операций создания, удаления и управления файлами.

Модуль pathlib, доступный с версии 3.4 Python, позволяет выполнять почти все распространенные операции над операционной системой, причем объектно-ориентированный синтаксис гораздо приятнее в использовании.

Класс Path

Класс Path позволяет создать объект, представляющий путь к файлу или папке на нашем компьютере.

Этот путь может существовать или не существовать на нашем жестком диске, это не является обязательным условием.

Path имеет несколько методов класса, позволяющих получить доступ к общим путям нашей операционной системы, например, к папке пользователя :

from pathlib import Path user_folder = Path.home()
Code language: JavaScript (javascript)

Можно также получить текущую папку:

from pathlib import Path current_folder = Path.cwd()
Code language: JavaScript (javascript)

Или создать конкретный путь, передав строку классу Path:

from pathlib import Path documents = Path("/Users/user/Documents")
Code language: JavaScript (javascript)

Примечание. Если мы отобразим объект, созданный на основе класса Path, то в итоге получим объект PosixPath. Этот объект представляет пути систем Linux и Mac OS. В Windows объект будет другим, потому что пути в Windows не такие, как в Mac и Linux. Это не изменяет методы и атрибуты, которые могут быть использованы для этого объекта.

>>> from pathlib import Path >>> documents = Path("/Users/user/Documents") >>> print(documents) PosixPath('/Users/user/Documents')
Code language: JavaScript (javascript)

Конкатенация путей

Чтобы объединить пути, очень просто, достаточно использовать косую черту:

from pathlib import Path home = Path.home() # PosixPath('/Users/user/') documents = home / "Documents" # PosixPath('/Users/user/Documents')
Code language: PHP (php)

Результат этой конкатенации возвращает новый объект PosixPath, поэтому мы можем объединить несколько строк подряд.

Примечание. pathlib работает с различными операционными системами и использует косую или обратную косую черту в зависимости от того, используете ли вы Mac/Linux или Windows. Это поведение похоже на функцию os.path.join модуля os.

from pathlib import Path home = Path.home() # PosixPath('/Users/user/') documents = home / "Documents" / "Project" # PosixPath('/Users/user/Documents/Project')
Code language: PHP (php)

Вы также можете использовать метод joinpath для объекта Path. Это может быть полезно, если у вас есть, например, список папок, которые вы хотите объединить (благодаря распаковке и оператору splat *):

from pathlib import Path home = Path.home() # PosixPath('/Users/user/') files = ['Projects', 'Django', 'blog'] home.joinpath(*files) # PosixPath('/Users/user/Projects/Django/blog')
Code language: PHP (php)

Если вы используете косые черты и хотите использовать метод объекта Path, не забывайте использовать круглые скобки для заключения конкатенированных путей:

from pathlib import Path home = Path.home() # PosixPath('/Users/user/') # Не сработает, потому что мы пытаемся получить атрибут суффикса строки "main.py". home / "Projcet" / "main.py".suffix # Со скобками это работает! (home / "Project" / "main.py").suffix
Code language: PHP (php)

Получение информации о пути

Благодаря объектно-ориентированному подходу, мы можем получить доступ ко многим сведениям о пути с помощью атрибутов объекта Path:

from pathlib import Path p = Path("/Users/user/Documents/index.html") p.name # "index.html" p.parent # "/Users/user/Documents" p.stem # "index" p.suffix # ".html" p.parts # ("/", "Users", "user", "documents", "index.html")
Code language: PHP (php)

Существуют также методы проверки существования и типа пути:

from pathlib import Path p = Path("/Users/user/Documents/index.html") p.exists() # True p.is_dir() # False p.is_file() # True
Code language: PHP (php)

И снова, когда путь может быть возвращен одним из этих атрибутов, мы получаем объект Path.

Поэтому мы можем несколько раз поместить один и тот же атрибут в конец, чтобы, например, подняться из нескольких папок:

from pathlib import Path p = Path("/Users/user/Documents/index.html") p.parent.parent # "/Users/user"
Code language: PHP (php)

Создание и удаление папок

Чтобы создать папку, можно использовать метод mkdir. Этот метод будет работать по умолчанию, только если папка не существует.

Вы можете использовать параметр exist_ok, чтобы указать, что вы не хотите, чтобы выдавалась ошибка, если папка уже существует:

from pathlib import Path file = Path("/Users/user/Documents/SiteWeb") file.mkdir() # Вызывает ошибку, если файл уже существует file.mkdir(exist_ok=True)
Code language: PHP (php)

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

from pathlib import Path # Папка SiteWeb и ее вложенные папки не существуют file = Path("/Users/user/Documents/SiteWeb/sources/css") # Вы можете создать все разом с помощью параметра parent file.mkdir(parents=True)
Code language: PHP (php)

Чтобы удалить папку, используйте метод rmdir:

from pathlib import Path file = Path("/Users/user/Documents/SiteWeb") file.rmdir()
Code language: JavaScript (javascript)

Этот метод работает только в том случае, если папка пуста.

Если папка содержит файлы или другие вложенные папки, этот метод не работает, и это единственный случай, когда нам придется вернуться к модулю shutil и функции rmtree:

import shutil from pathlib import Path file = Path("/Users/user/Documents/SiteWeb") shutil.rmtree(file)
Code language: JavaScript (javascript)

Создание, чтение и запись в файл

Для создания и удаления файла можно использовать методы touch и unlink соответственно:

from pathlib import Path file = Path("/Users/user/Documents/SiteWeb/index.html") file.touch() file.unlink()
Code language: JavaScript (javascript)

Для записи содержимого в файл мы используем метод write_text:

from pathlib import Path file = Path("/Users/user/Documents/SiteWeb/index.html") file.write_text("Главная страница")
Code language: JavaScript (javascript)

При использовании метода touch не обязательно предварительно создавать файл.

Согласитесь, что это быстрее, чем делать :

from pathlib import Path file = Path("/Users/user/Documents/SiteWeb/index.html") with open(file, "w") as f: f.write("Главная страница")
Code language: JavaScript (javascript)

Таким же образом для чтения содержимого файла мы можем использовать метод read_text:

>>> from pathlib import Path >>> file = Path("/Users/user/Documents/SiteWeb/index.html") >>> file.read_text() "Главная страница"
Code language: JavaScript (javascript)

Сканирование папки

Где pathlib действительно потрясает, так это в способности сканировать папки вашего компьютера с помощью методов, которые гораздо легче запомнить, чем модуль glob.

Чтобы получить все файлы и папки внутри папки, можно использовать метод iterdir:

from pathlib import Path for f in Path.home().iterdir(): print(f.name)
Code language: CSS (css)

Этот метод можно комбинировать с методом is_dir для получения только папок (здесь с помощью понимания списка):

from pathlib import Path files = [d for d in Path.home().iterdir() if d.is_dir()]
Code language: JavaScript (javascript)

Для более гибкого сканирования папки можно использовать метод glob. Например, вы можете получить только файлы с расширением .png:

from pathlib import Path for f in Path.home().glob("*.png"): print(f.name)
Code language: CSS (css)

Если вы хотите сканировать папку рекурсивно, просто используйте rglob вместо glob :

from pathlib import Path for f in Path.home().rglob("*.png"): print(f.name)
Code language: CSS (css)

Несколько практических примеров

Вот несколько практических примеров того, насколько гибким и простым является использование pathlib.

Добавление суффикса к имени файла

from pathlib import Path p = Path.home() / "image.png" # "/Users/user/image.png" p.parent / (p.stem + "-lowres" + p.suffix) # "/Users/user/image-lowres.png"
Code language: PHP (php)

Сортировка файлов по расширению

from pathlib import Path dirs = {".jpg": "Images", ".gif": "Images", ".mp4": "Videos", ".pdf": "Documents", ".mp3": "Music", ".wav": "Music"} sort_dir = Path.home() / "Сортировка" files = [f for f in tri_dir.iterdirs() if f.is_file()] for f in files: # Если для расширения не найдено соответствия, файлы помещаются в папку Others output_dir = sort_dir / dirs.get(f.suffix, "Others") output_dir.mkdir(exist_ok=True) f.rename(output_dir / f.name)
Code language: PHP (php)

Для перемещения файла можно использовать метод rename.

Создание константы папки с помощью __file__

from pathlib import Path SOURCE_FILE = Path(__file__).resolve() # resolve позволяет разрешать символические ссылки SOURCE_DIR = SOURCE_FILE.parent ROOT_DIR = SOURCE_FILE.parent DATA_DIR = SOURCE_DIR / "DATA"
Code language: PHP (php)

Заключение

Я надеюсь, что после этой статьи вы сможете увидеть преимущество использования pathlib для всего, что связано с управлением файлами и папками в вашей операционной системе.

По-прежнему важно знать модули os, shutil и glob, поскольку в интернете можно найти множество скриптов, использующих их. Но если вы начинаете новый проект с Python 3.4+, то не сомневайтесь ни секунды!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *