May 10, 2022

pathlib в Python

В богохранимом PHP есть такая встроенная глобально доступная функция file_get_contents. Она читает локальный или удаленный (http) ресурс в строку. Например:

file_content = file_get_contents("./localfile.txt")
webpage_content = file_get_contents("https://ya.ru")

Удобненько. В Python во всех материалах показывают чтение текстового файла так:

with open("./localfile.txt", "r") as f:
    file_content = f.read()

Больше кода, две строки, табуляция — меньше удовольствия. Однако есть ещё вот такой вариант:

from pathlib import Path

file_contents = Path("./localfile.txt").read_text()

file_contents = Path("./localfile.txt").write_text("some string")

Мне нравится такой вариант. Да, pathlib импортировать надо, но его всё равно часто надо импортировать при работе с путями к файлам. Скажем, во многих материалах для получения склейки пути используется конструкция os.path.join(), то есть, чтобы получить путь "current/file.txt" в *nix или "current\file.txt" в Windows пишут os.path.join("current", "file.txt"). И вот то же самое можно сделать с Path таким образом: Path("current", "file.txt"). Импортировали Path и удобно читаем файл:

import json
from pathlib import Path

from django.conf import settings

users = json.loads(Path(settings.BASE_DIR, "users.json").read_text())

Аналогичное без Path:

import json
import os

from django.conf import settings

with open(os.path.join(settings.BASE_DIR, "users.json"), "r") as f:
    users = json.load(f)

Первый вариант с Path мне нравится определённо больше.

Кстати, можно и так пути склеивать (аналогично будет подставляться правильный разделитель директорий для текущей ОС):

html_path = Path("www") / "html"  # "www/html" in *nix

Вообще в pathlib удобностей много, например:

  • Получить текущую директорию: Path.cwd() (от current working directory)
  • Проверить существование файла/директории: Path.exists("/home/user/filename")
  • Найти все .py файлы в текущей директории на любом уровне вложенности: Path(".").glob("**/*.py")
  • Итерироваться по директории: Path("./dir").iterdir()
  • Получить родителя директории: Path("/var/www/html/file.txt").parent, результатом будет путь "/var/www/html/". Подняться на 3 уровня вверх: Path("/var/www/html/file.txt").parents[2], результатом будет путь: /var.