Python pathlib: пути, файлы и папки без os.path

Категория: Python · Язык: Python · Обновлено:

Модуль pathlib описывает пути как объекты: части пути берутся атрибутами, пути склеиваются оператором /, а чтение, запись, поиск и создание папок доступны методами. Это современная замена функциям os.path, одинаково работающая на Linux, macOS и Windows.

Создать пути и папки

Python
from pathlib import Path

base = Path("demo")
base.mkdir(parents=True, exist_ok=True)       # создать папку, не падать если она есть
(base / "data").mkdir(exist_ok=True)

file = base / "notes.txt"                     # оператор / склеивает части
file.write_text("привет\n", encoding="utf-8")
(base / "data" / "a.csv").write_text("1,2\n", encoding="utf-8")

Параметр parents=True создаёт и все недостающие родительские папки, exist_ok=True подавляет ошибку, если папка уже есть.

Части пути

Python
print(file.as_posix())                 # demo/notes.txt
print(file.name)                       # notes.txt
print(file.stem)                       # notes
print(file.suffix)                     # .txt
print(file.parent)                     # demo
print(file.with_suffix(".md").name)    # notes.md
print(file.with_name("todo.txt").name) # todo.txt
print(Path("a/b/c.tar.gz").suffixes)   # ['.tar', '.gz']

Проверки

Python
print(file.exists())                   # True
print(file.is_file())                  # True
print(base.is_dir())                   # True
print(file.stat().st_size)             # 13

Размер в байтах равен 13: шесть русских букв по два байта в UTF-8 и символ конца строки.

Прочитать и записать файл

Python
print(file.read_text(encoding="utf-8").strip())   # привет
file.write_text("новый текст", encoding="utf-8")
print(file.read_bytes()[:6])                      # b'\xd0\xbd\xd0\xbe\xd0\xb2'

Перебрать и найти файлы

Python
print(sorted(p.name for p in base.iterdir()))       # ['data', 'notes.txt']
print(sorted(p.name for p in base.glob("*.txt")))   # ['notes.txt']
print([p.as_posix() for p in base.rglob("*.csv")])  # ['demo/data/a.csv']

glob("*.txt") ищет в одной папке, rglob("*.csv") во всех вложенных.

Переименовать, переместить, удалить

Python
file.rename(base / "renamed.txt")                    # переименовать или переместить
(base / "renamed.txt").unlink()                      # удалить файл
(base / "data" / "a.csv").unlink()
(base / "data").rmdir()                              # удалить пустую папку
base.rmdir()
print(base.exists())                                 # False

Для удаления папки вместе с содержимым используйте shutil.rmtree(base).

Специальные пути

Python
print(Path.cwd() == Path(".").resolve())    # True
print(Path.home().is_absolute())            # True
print(Path("a/../b").resolve().name)        # b

В скрипте путь к его собственной папке получают как Path(__file__).resolve().parent, это не зависит от места запуска.

Соответствие os.path

Задача

os.path

pathlib

Склеить путь

os.path.join(a, b)

Path(a) / b

Имя файла

os.path.basename(p)

p.name

Папка файла

os.path.dirname(p)

p.parent

Расширение

os.path.splitext(p)[1]

p.suffix

Существует ли

os.path.exists(p)

p.exists()

Создать папки

os.makedirs(p, exist_ok=True)

p.mkdir(parents=True, exist_ok=True)

Частые вопросы

Можно ли передавать Path в open и другие функции?

Да, начиная с Python 3.6 функции стандартной библиотеки принимают объекты Path. Если нужна строка, используйте str(path).

Почему в Windows путь печатается с обратными косыми?

Path использует разделитель системы. Чтобы получить одинаковую запись везде, вызывайте path.as_posix().