Применение pathlib для управления файлами и каталогами

Раздел: Системное администрирование -> Файловый ввод-вывод

Введение в pathlib

Модуль pathlib предоставляет объектно-ориентированный интерфейс для работы с файловыми путями. В системном администрировании он заменяет громоздкие вызовы os.path и упрощает переносимый код. Основной класс - Path, который представляет путь в файловой системе.

Как эффективно работать с путями, не прибегая к строковым операциям?

Основной подход - создание объекта Path и использование его методов. Например, для чтения файла:

from pathlib import Path
# создаем объект пути
p = Path('/var/log/syslog')
# читаем содержимое (рекомендуется для небольших файлов)
content = p.read_text()
print(content[:200])

ввод программ на python (ввод данных в программе python)

# Вывод (примерно):
Jun 12 10:15:32 server kernel: ...

Python file io (ввод-вывод файлов в python)

Цель: получить унифицированный и безопасный способ работы с файлами. Случаи использования: чтение конфигов, запись логов, создание временных директорий.

Типичная ошибка: неверный путь или отсутствие файла. Path.read_text() бросает FileNotFoundError. Решение - проверять p.exists() или ловить исключение.

Когда уместно использовать os.path вместо pathlib?

Хотя pathlib предпочтительнее, в старом коде или при необходимости быстрой конкатенации строк можно применить os.path.join. Но pathlib переопределяет оператор '/' для путей:

from pathlib import Path
base = Path('/etc')
full = base / 'nginx' / 'sites-enabled' / 'default'
print(full)

Python temp files (временные файлы в python)

/etc/nginx/sites-enabled/default

Python index files (индексация файлов в python)

Цель: избежать путаницы с разделителями. Случаи использования: динамическое построение путей.

Проблема: при работе с Windows и Linux разделители отличаются. Path решает это автоматически.

Как обрабатывать ошибки при работе с pathlib?

Используйте try/except. Например, при удалении файла:

from pathlib import Path
p = Path('/tmp/test.txt')
try:
    p.unlink()
    print(f'Удален {p}')
except FileNotFoundError:
    print('Файл не найден')
except PermissionError:
    print('Нет прав')

File python class (класс для работы с файлами в python)

Удален /tmp/test.txt

Python file utf 8 (кодировка utf-8 для файлов в python)

Цель: устойчивость скрипта к внешним условиям. Случаи: массовая очистка директорий, обработка логов.

Ошибка: забыть закрыть файл при записи. Path.write_text() открывает и закрывает сам, но если нужен бинарный режим, используйте write_bytes().

Как получить расширение файла или изменить его?

Свойства suffix, stem, with_suffix:

log = Path('app.log')
print(f'Расширение: {log.suffix}')
print(f'Имя без расширения: {log.stem}')
new_log = log.with_suffix('.bak')
print(f'Резервная копия: {new_log}')

Python config files (конфигурационные файлы в python)

Расширение: .log
Имя без расширения: app
Резервная копия: app.bak

Python copy file (копирование файла в python)

Цель: манипуляции с именами. Случаи: переименование, архивация.

Нюанс: suffix возвращает только последнее расширение; для .tar.gz нужно обрабатывать отдельно.

Как найти файлы по шаблону в директории?

Методы glob и rglob:

from pathlib import Path
d = Path('/var/log')
# все .log файлы в текущей папке
for f in d.glob('*.log'):
    print(f.name)
# рекурсивно все .gz
for f in d.rglob('*.gz'):
    print(f)

Python log file (логирование в файл в python)

текущая папка:
syslog.log
auth.log
рекурсивно:
/var/log/syslog.1.gz
/var/log/auth.log.1.gz

Python file methods (методы работы с файлами в python)

Цель: обход каталогов. Случаи: поиск устаревших логов, сбор отчетов.

Ошибка: glob не чувствителен к регистру в некоторых ОС, что может дать неожиданные результаты.

Как рекурсивно обойти все поддиректории?

Используйте rglob('*') или iterdir():

for path in Path('/etc').rglob('*'):
    if path.is_file():
        print(f'{path} размер {path.stat().st_size}')

File models in python (модели файлов в python)

/etc/hosts размер 200
/etc/nginx/nginx.conf размер 3740
...

File handle python (обработка файлов в python)

Цель: полная инвентаризация. Случаи: аудит системы, подсчет дискового пространства.

Проблема: слишком глубокая вложенность или много файлов может замедлить выполнение. Используйте is_dir() для фильтрации.

Как создать символическую ссылку?

Метод symlink_to:

from pathlib import Path
original = Path('/var/log/syslog')
link = Path('/tmp/syslog_link')
link.symlink_to(original)
print(f'Ссылка {link} указывает на {link.resolve()}')

Python open file read (открытие файла для чтения в python)

Ссылка /tmp/syslog_link указывает на /var/log/syslog

Python file position (позиционирование в файле python)

Цель: гибкое управление ссылками. Случаи: временные маппинги, администрирование.

Ошибка: PermissionError, если нет прав. Также на Windows требуется особый режим.

Как получить информацию о файле (владелец, права)?

Используйте stat() и модуль pwd:

from pathlib import Path
import pwd, stat
p = Path('/etc/passwd')
st = p.stat()
uid = st.st_uid
print(f'Владелец: {pwd.getpwuid(uid).pw_name}')
print(f'Права: {oct(st.st_mode & 0o777)}')

Python line find (поиск строки в файле python)

Владелец: root
Права: 0o644

Цель: анализ безопасности. Случаи: проверка корректности прав, выявление нестандартных владельцев.

Нюанс: для владельца на Windows нужно использовать другой способ.

- Key files python (работа с ключевыми файлами в python)
- Python file w (режим записи в файл в python)
- Python file modes (режимы открытия файлов в python)

Дополнительные примеры с pathlib

Массовое переименование файлов с изменением расширения

Пример
from pathlib import Path

dir_path = Path('/tmp/backup')
for file in dir_path.iterdir():
    if file.is_file() and file.suffix == '.tmp':
        new_name = file.with_suffix('.bak')
        file.rename(new_name)
        print(f'{file.name} -> {new_name.name}')
test1.tmp -> test1.bak
old.tmp -> old.bak

Проверка, является ли путь абсолютным, и создание относительного

Пример
from pathlib import Path

a = Path('/var/log/syslog')
b = Path('/var/log')
print(f'{a.is_absolute()=}')
print(f'{b.is_absolute()=}')
rel = a.relative_to(b)
print(f'Относительный: {rel}')
a.is_absolute()=True
b.is_absolute()=True
Относительный: syslog

Работа с временными файлами через tempfile и Path

Пример
from pathlib import Path
import tempfile

with tempfile.NamedTemporaryFile(delete=False, suffix='.txt') as tf:
    temp_path = Path(tf.name)
    temp_path.write_text('Временные данные')

print(f'Создан временный файл: {temp_path}')
# удаление после работы
temp_path.unlink()
Создан временный файл: /tmp/tmpabc123.txt

Копирование содержимого каталога с сохранением структуры

Пример
from pathlib import Path
import shutil

src = Path('/home/user/myproject')
dst = Path('/backup/project')

if not dst.exists():
    dst.mkdir(parents=True)

for item in src.rglob('*'):
    if item.is_file():
        # создаем целевую поддиректорию
        relative = item.relative_to(src)
        target = dst / relative
        target.parent.mkdir(parents=True, exist_ok=True)
        shutil.copy2(item, target)

print('Копирование завершено')
Копирование завершено

Безопасное чтение последних N строк лога

Пример
from pathlib import Path
from collections import deque

log = Path('/var/log/syslog')
n = 10
with log.open('r') as f:
    last_lines = deque(f, maxlen=n)
for line in last_lines:
    print(line, end='')
Jun 12 12...

Проверка времени последнего изменения и архивация

Пример
from pathlib import Path
import time

files = [Path('/var/log/auth.log'), Path('/var/log/syslog')]
deadline = time.time() - 86400  # 1 день
for f in files:
    if f.exists() and f.stat().st_mtime < deadline:
        print(f'{f.name} старее 1 дня, gzip для архивации')
        # shutil.make_archive(...)
auth.log старее 1 дня, gzip для архивации

Использование pathlib в Python - comments

En
Python pathlib path (python)