Pathlib в Python: практическое руководство для начинающих (с примерами)

Pathlib в Python: практическое руководство для начинающих (с примерами)

Pathlib в Python: практическое руководство для начинающих (с примерами)

Pathlib в Python — это стандартный модуль, который заменяет громоздкие операции с os и os.path объектно-ориентированным интерфейсом. Он делает работу с путями и файлами единообразной на Windows, macOS и Linux. В этой статье вы узнаете базовые и чуть более продвинутые приёмы, получите готовые рецепты и поймёте, когда pathlib предпочтительнее классических функций.

Почему именно pathlib?

  • Объектный интерфейс: путь — это объект Path, у которого есть методы и свойства.
  • Кросс‑платформенность: не нужно думать о слешах — Path сам подстроится под ОС.
  • Лаконичный синтаксис: оператор / безопасно соединяет части путей.
  • Быстрый старт с Path

    from pathlib import Path
    
    # Текущая директория проекта
    p = Path.cwd()
    print(p)  # например: /Users/me/project
    
    # Безопасное соединение путей
    logs_dir = p / "logs" / "2026"
    print(logs_dir)
    
    # Относительный и абсолютный путь
    print(logs_dir.is_absolute())
    print(logs_dir.resolve())
    

    Проверки: существует ли файл или папка?

    from pathlib import Path
    
    path = Path("data/input.csv")
    print(path.exists())   # True, если путь существует
    print(path.is_file())  # True, если это файл
    print(path.is_dir())   # True, если это директория
    

    Создание директорий и файлов

    from pathlib import Path
    
    data_dir = Path("data/raw")
    # Создать все недостающие папки
    data_dir.mkdir(parents=True, exist_ok=True)
    
    # Создать пустой файл (если нет)
    (Path("data/raw/.keep")).touch(exist_ok=True)
    

    Чтение и запись файлов: просто и безопасно

    from pathlib import Path
    
    text_path = Path("notes/today.txt")
    text_path.parent.mkdir(parents=True, exist_ok=True)
    
    # Запись текста
    text_path.write_text("Привет, pathlib!n", encoding="utf-8")
    
    # Дозапись
    with text_path.open("a", encoding="utf-8") as f:
        f.write("Ещё одна строка.n")
    
    # Чтение текста
    content = text_path.read_text(encoding="utf-8")
    print(content)
    
    # Работа с байтами
    bin_path = Path("data/blob.bin")
    bin_path.write_bytes(b"x00x01x02")
    print(bin_path.read_bytes())
    

    Обход директорий: iterdir, glob и rglob

    from pathlib import Path
    
    base = Path("data")
    
    # Все элементы в директории (без рекурсии)
    for entry in base.iterdir():
        print(entry, "DIR" if entry.is_dir() else "FILE")
    
    # Поиск по маске (только в текущей папке)
    for csv_file in base.glob("*.csv"):
        print("CSV:", csv_file)
    
    # Рекурсивный поиск по подпапкам
    for py_file in base.rglob("*.py"):
        print("Python-файл:", py_file)
    
    # Фильтрация по расширению
    images = sorted((base.rglob("*")), key=lambda p: p.name)
    images = [p for p in images if p.suffix.lower() in {".png", ".jpg", ".jpeg"}]
    print(len(images), "изображений найдено")
    

    Домашняя директория и относительные пути

    from pathlib import Path
    
    home = Path.home()
    print(home)
    
    config = Path("~/.config/myapp/settings.ini").expanduser()
    print(config)
    
    # Получить абсолютный путь и нормализовать ссылки/../.
    print(config.resolve())
    
    # Относительный путь от папки проекта
    project = Path.cwd()
    print(config.relative_to(home))  # относительный к домашней
    

    Метаданные файла: размер и время изменения

    from pathlib import Path
    from datetime import datetime
    
    path = Path("data/input.csv")
    if path.exists():
        st = path.stat()
        print("Размер, байты:", st.st_size)
        mtime = datetime.fromtimestamp(st.st_mtime)
        print("Изменён:", mtime.isoformat())
    

    Переименование, перемещение и удаление

    from pathlib import Path
    
    src = Path("data/raw/old.csv")
    dst = Path("data/processed/new.csv")
    dst.parent.mkdir(parents=True, exist_ok=True)
    
    # Переименование или перемещение
    if src.exists():
        src.rename(dst)  # или src.replace(dst) для перезаписи без ошибок
    
    # Удаление файла
    try:
        dst.unlink()  # удалит файл; для папки используйте rmdir()
    except FileNotFoundError:
        pass
    

    Windows vs Linux/macOS: что учитывать

  • Не склеивайте пути вручную обратными слешами: используйте Path(...)
    и оператор / или joinpath().
  • Если нужно работать с путями другой платформы без доступа к ФС, используйте PureWindowsPath или PurePosixPath (они не трогают файловую систему).
  • from pathlib import PureWindowsPath, PurePosixPath
    
    win = PureWindowsPath("C:\Users\me\file.txt")
    posix = PurePosixPath("/var/log/app.log")
    print(win.drive, posix.anchor)
    

    Типичные ошибки и как их избежать

  • Ошибка: соединять строки путей через «+» или f-строки. Решение: p / "sub" / "file.txt" или p.joinpath("sub", "file.txt").
  • Ошибка: забывать про кодировку при чтении/записи текста. Решение: всегда указывать encoding="utf-8".
  • Ошибка: удалять директорию через unlink(). Решение: для папок используйте rmdir() (пустая) или shutil.rmtree() (непустая).
  • Мини‑проект: разбор папки «Загрузки» по расширениям

    Сгруппируем файлы по типу и разложим в подпапки. Отличная практика для pathlib!

    from pathlib import Path
    from collections import defaultdict
    import shutil
    
    DOWNLOADS = Path.home() / "Downloads"
    TARGET = DOWNLOADS / "_sorted"
    TARGET.mkdir(exist_ok=True)
    
    GROUPS = {
        "images": {".png", ".jpg", ".jpeg", ".gif", ".webp"},
        "docs":   {".pdf", ".docx", ".xlsx", ".pptx", ".txt"},
        "archives": {".zip", ".rar", ".7z", ".tar", ".gz"},
    }
    
    buckets = defaultdict(list)
    for file in DOWNLOADS.iterdir():
        if file.is_file():
            ext = file.suffix.lower()
            placed = False
            for name, exts in GROUPS.items():
                if ext in exts:
                    buckets[name].append(file)
                    placed = True
                    break
            if not placed:
                buckets["other"].append(file)
    
    for name, files in buckets.items():
        folder = TARGET / name
        folder.mkdir(exist_ok=True)
        for f in files:
            dest = folder / f.name
            try:
                # replace перезапишет, если файл уже есть
                shutil.move(str(f), str(dest))
            except Exception as e:
                print("Не удалось переместить", f, "->", dest, e)
    
    print("Готово! Файлы разложены в:", TARGET)
    

    Итоги

    Модуль pathlib делает работу с путями и файлами в Python простой, читаемой и безопасной. Начинайте новые проекты с Path вместо os.path, используйте glob и rglob для поиска, read_text/write_text для удобной работы с текстом и не забывайте про кросс‑платформенность. Хотите системно прокачаться и закрыть пробелы в основах и практике? Рекомендую внимательно посмотреть программу курса «Python с нуля до уровня Гуру — пошаговый интенсив для быстрого старта».

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий