Файловые пути в Python: примеры и объяснения

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

Работа с путями в Python 3

Основной и наиболее современный способ работы с путями в Python 3 - модуль pathlib. Он предоставляет объектно-ориентированный интерфейс для путей файловой системы, автоматически адаптируясь под операционную систему.

Как создать объект пути и выполнять базовые операции?

from pathlib import Path

home = Path.home()
print(home)  # /home/user или C:\Users\user

config = home / "config" / "app.conf"
print(config)

print(config.parent)
print(config.name)
print(config.stem)
print(config.suffix)

if config.exists():
    print("Файл существует")
else:
    print("Файл не найден")

text = config.read_text(encoding="utf-8")
print(text[:50])

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

  • Проблема: путаница с обратными слешами в Windows при использовании строк. Решение: pathlib использует правильные разделители автоматически.
  • Типичная ошибка: неявное преобразование в строку для передачи в API, ожидающий строку. Решение: использовать str(path) или path.as_posix() для кросс-платформенного представления.
  • Проблема: несуществующий путь, но объект создается без ошибок. Решение: проверка exists() и resolve(strict=True) для верификации.

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

Как объединить части пути без pathlib, используя os.path?

Для старых проектов или простых операций можно применять функции модуля os.path. Они работают со строками.

import os

base = "/var/log"
filename = "system.log"
full = os.path.join(base, filename)
print(full)  # /var/log/system.log

abs_path = os.path.abspath(full)
print(abs_path)

norm = os.path.normpath("/var/log/../log/./system.log")
print(norm)  # /var/log/system.log

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

Проблема: разные разделители в Windows и Unix. Решение: os.path.join обрабатывает это, но результат может быть неоднозначным. Лучше избегать жестко заданных слешей.

Типичная ошибка: использование конкатенации строк через '+' в кроссплатформенном коде. Решение: всегда использовать os.path.join.

Как получить путь к домашнему каталогу пользователя или раскрыть переменные окружения?

Функции os.path.expanduser и os.path.expandvars позволяют подставлять ~ и переменные.

import os

path = os.path.expanduser("~/Documents/report.txt")
print(path)  # /home/user/Documents/report.txt

path = os.path.expandvars("$HOME/Downloads/${USER}_notes.txt")
print(path)  # /home/user/Downloads/user_notes.txt

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

Проблема: переменная может отсутствовать. Решение: проверка с помощью os.environ.get() до использования.

Типичная ошибка: использование expanduser на Windows с неправильным слешем. Решение: после подстановки можно применить normpath.

Как манипулировать частями пути без доступа к файловой системе?

Класс pathlib.PurePath (или PurePosixPath, PureWindowsPath) предоставляет все методы pathlib, но без дисковых операций (exists, open и т.д.). Это полезно для обработки путей как строк.

from pathlib import PurePosixPath

path = PurePosixPath("/data/project/file.txt")
new_path = path.with_name("backup.txt")
print(new_path)  # /data/project/backup.txt

parent2 = path.parents[1] if len(path.parents) > 1 else path
print(parent2)  # /data

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

- Python file utf 8 (кодировка utf-8 для файлов в python)
- Python config files (конфигурационные файлы в python)
- Python copy file (копирование файла в python)

Расширенные примеры работы с путями

Ниже приведены продвинутые сценарии, которые часто встречаются в задачах системного администрирования.


Пример 1: рекурсивный обход всех файлов в директории

Пример
from pathlib import Path

root = Path("/var/log")
# rglob возвращает все пути, включая поддиректории
for file in root.rglob("*.log"):
    if file.is_file():
        print(f"{file.name} - {file.stat().st_size} байт")
syslog.log - 12450 байт
audit.log - 80400 байт
dpkg.log - 2330 байт
...

Пояснение: метод rglob(pattern) ищет файлы, соответствующие шаблону, во всех вложенных папках. file.stat().st_size возвращает размер в байтах. Следует учитывать, что при большом количестве файлов обход может быть медленным.


Пример 2: поиск всех файлов по сложному шаблону с использованием glob

Пример
from pathlib import Path

home = Path.home()
# найти все изображения PNG, JPEG в домашней папке
for img in home.glob("**/*.{png,jpg,jpeg}"):
    print(img.relative_to(home))
Documents/photo.png
Pictures/image.jpg
Downloads/screenshot.jpeg

Пояснение: glob с двумя звездочками (**) выполняет рекурсивный поиск. Фигурные скобки задают несколько расширений. relative_to(home) выводит путь относительно начальной точки.


Пример 3: работа с символическими ссылками

Пример
from pathlib import Path

# создать символическую ссылку (при наличии прав)
target = Path("/tmp/source.log")
link = Path("/tmp/link.log")
if not link.exists():
    link.symlink_to(target)

# проверить, является ли путь ссылкой
print(link.is_symlink())  # True
# куда указывает ссылка
print(link.readlink())    # /tmp/source.log
True
/tmp/source.log

Пояснение: symlink_to() создает ссылку, readlink() возвращает целевой путь. На Windows требуется включенный режим разработчика или права администратора.


Пример 4: получение метаданных файла (время изменения, размер, права доступа)

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

file = Path("/etc/passwd")
stat = file.stat()
print(f"Размер: {stat.st_size} байт")
print(f"Последнее изменение: {time.ctime(stat.st_mtime)}")
print(f"Права: {oct(stat.st_mode)[-3:]}")  # например, 755
Размер: 2350 байт
Последнее изменение: Mon Jan 15 12:34:56 2024
Права: 644

Пояснение: stat() возвращает объект os.stat_result, из которого извлекаются числовые значения. Для изменения времени можно использовать методы touch() для обновления отметки.


Пример 5: создание временных файлов и путей с использованием tempfile

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

# создаем временную директорию
with tempfile.TemporaryDirectory() as tmpdir:
    tmp_path = Path(tmpdir)
    # создаем временный файл
    log_file = tmp_path / "temp.log"
    log_file.write_text("временные данные")
    print(f"Создан временный файл: {log_file}")
    # после выхода из with директория удалится автоматически

# альтернатива: NamedTemporaryFile
with tempfile.NamedTemporaryFile(suffix=".conf", delete=False) as tmp:
    tmp_name = tmp.name
    tmp.write(b"config")
print(f"Временный файл не удален: {tmp_name}")
Создан временный файл: /tmp/tmpabc123/temp.log
Временный файл не удален: /tmp/tmpxyz.conf

Пояснение: TemporaryDirectory автоматически удаляет папку. NamedTemporaryFile с параметром delete=False оставляет файл после закрытия. Такие приёмы полезны для обработки больших временных данных.

Путь к Python 3 - comments

En
Python 3 path (python)