os.pathМодуль os.path — это подмодуль os, предназначенный для работы с путями файлов и папок. Он помогает создавать переносимые пути между Windows, Linux и macOS, а также проверять и модифицировать пути.
Основные преимущества:
import os
import os.path # или просто from os import path
# Проверка доступности модуля
print(f"Модуль os.path доступен: {hasattr(os, 'path')}")
os.path.join(path, paths) — объединяет части пути. Создает корректные пути, автоматически добавляя правильные разделители для текущей ОС.
import os.path
# 1. Создать путь к файлу
full_path = os.path.join("C:/Users/Ivan", "Documents", "notes.txt")
print(f"Полный путь: {full_path}")
# 2. Создать путь к вложенной папке
folder_path = os.path.join("project", "src", "utils")
print(f"Путь к папке: {folder_path}")
# 3. Объединение с динамическими именами
folder = "logs"
file = "log1.txt"
log_path = os.path.join(folder, file)
print(f"Путь к логу: {log_path}")
# 4. Кроссплатформенный пример
paths = ["home", "user", "projects", "app", "config.ini"]
config_path = os.path.join(*paths)
print(f"Кроссплатформенный путь: {config_path}")
# 5. Объединение с абсолютными и относительными путями
result = os.path.join("/home/user", "documents", "..", "projects")
print(f"Путь с '..': {result}")
os.path.normpath(path) — нормализует путь. Убирает лишние слэши и обрабатывает . (текущая директория) и .. (родительская директория).
import os.path
# 1. Простой пример
normalized = os.path.normpath("project//src/../utils")
print(f"Нормализованный путь: {normalized}")
# 2. Нормализация с точками
path1 = os.path.normpath("./folder1/./folder2/../file.txt")
print(f"Нормализовано: {path1}")
# 3. Нормализация в Windows-стиле (даже на Linux)
path2 = "folder1\\folder2/../folder3"
normalized2 = os.path.normpath(path2)
print(f"Смешанные слэши: {normalized2}")
# 4. Практическое применение
user_path = "C:\\Users\\\\John\\Documents\\..\\Desktop\\file.txt"
clean_path = os.path.normpath(user_path)
print(f"Очищенный путь: {clean_path}")
os.path.commonpath(paths) — общий путь для списка путей. Находит самый длинный общий путь для нескольких путей.
import os.path
# 1. Поиск общего пути
paths = [
"/home/user/docs/file1.txt",
"/home/user/docs/reports/report.pdf",
"/home/user/images/photo.jpg"
]
common = os.path.commonpath(paths)
print(f"Общий путь: {common}")
# 2. С Windows-путями
windows_paths = [
"C:\\Users\\John\\Documents\\file1.txt",
"C:\\Users\\John\\Desktop\\file2.txt",
"C:\\Users\\John\\Downloads\\file3.txt"
]
common_win = os.path.commonpath(windows_paths)
print(f"Общий путь (Windows): {common_win}")
os.path.abspath(path) — абсолютный путь. Возвращает полный путь от корня файловой системы.
import os.path
# 1. Абсолютный путь для текущего файла
abs_path = os.path.abspath("data.txt")
print(f"Абсолютный путь к data.txt: {abs_path}")
# 2. Абсолютный путь для вложенной папки
log_path = os.path.abspath("logs/log1.txt")
print(f"Абсолютный путь к логу: {log_path}")
# 3. Использование для открытия файла
try:
with open(os.path.abspath("notes.txt")) as f:
content = f.read()
print(f"Содержимое notes.txt: {content[:50]}...")
except FileNotFoundError:
print("Файл не найден")
# 4. Преобразование относительного пути в абсолютный
relative = "../parent_folder/file.txt"
absolute = os.path.abspath(relative)
print(f"Относительный: {relative}")
print(f"Абсолютный: {absolute}")
os.path.relpath(path, start='.') — относительный путь. Возвращает путь от start до path.
import os.path
import os
# 1. Относительный путь до файла
rel_path = os.path.relpath("C:/Users/Ivan/Documents/notes.txt", "C:/Users/Ivan")
print(f"Относительный путь: {rel_path}")
# 2. Относительный путь между папками
project_path = os.path.relpath("project/src/utils", "project")
print(f"Относительный путь в проекте: {project_path}")
# 3. Использование для логирования
base = os.getcwd()
file = os.path.join(base, "data/output.txt")
relative_to_base = os.path.relpath(file, base)
print(f"Относительно текущей директории: {relative_to_base}")
# 4. Создание переносимых путей
def create_portable_path(base_dir, target_path):
"""Создает путь, который будет работать при перемещении проекта"""
return os.path.relpath(target_path, base_dir)
portable = create_portable_path("/home/user/project", "/home/user/project/data/config.ini")
print(f"Переносимый путь: {portable}")
os.path.isabs(path) — проверка абсолютного пути. Проверяет, является ли путь абсолютным.
import os.path
# 1. Проверка абсолютных путей
paths_to_check = [
"/home/user/file.txt", # Абсолютный (Unix)
"C:\\Windows\\system32", # Абсолютный (Windows)
"./relative/file.txt", # Относительный
"file.txt", # Относительный
"../parent/file.txt" # Относительный
]
for path in paths_to_check:
is_absolute = os.path.isabs(path)
print(f"{path:30} -> Абсолютный: {is_absolute}")
os.path.exists(path) — существует ли путь. Проверяет существование файла или директории.
import os.path
import os
# 1. Проверка файла
file_exists = os.path.exists("notes.txt")
print(f"Файл notes.txt существует: {file_exists}")
# 2. Проверка папки
folder_exists = os.path.exists("logs")
print(f"Папка logs существует: {folder_exists}")
# 3. Условное создание папки
if not os.path.exists("backup"):
os.mkdir("backup")
print("Папка backup создана")
# 4. Проверка нескольких путей
paths_to_check = ["config.json", "data.csv", "images/", "output/"]
print("\nПроверка существования путей:")
for path in paths_to_check:
exists = os.path.exists(path)
status = "✅ существует" if exists else "❌ не существует"
print(f" {path:20} {status}")
os.path.isfile(path) — является ли файлом. Проверяет, является ли путь файлом.
import os.path
# 1. Проверка файла
is_file = os.path.isfile("data.txt")
print(f"data.txt является файлом: {is_file}")
# 2. Использование перед чтением
config_file = "config.txt"
if os.path.isfile(config_file):
with open(config_file, 'r') as f:
config_content = f.read()
print(f"Конфиг прочитан, размер: {len(config_content)} символов")
else:
print(f"Файл {config_file} не найден или не является файлом")
# 3. Проверка перед удалением
temp_file = "old.txt"
if os.path.isfile(temp_file):
os.remove(temp_file)
print(f"Файл {temp_file} удален")
else:
print(f"Файл {temp_file} не существует для удаления")
# 4. Фильтрация только файлов в директории
def list_files_only(directory):
"""Возвращает список только файлов в директории"""
return [item for item in os.listdir(directory)
if os.path.isfile(os.path.join(directory, item))]
files = list_files_only(".")
print(f"\nФайлы в текущей директории: {files}")
os.path.isdir(path) — является ли папкой. Проверяет, является ли путь директорией.
import os.path
import os
# 1. Проверка папки
is_directory = os.path.isdir("logs")
print(f"logs является папкой: {is_directory}")
# 2. Создание папки при отсутствии
backup_dir = "backup"
if not os.path.isdir(backup_dir):
os.mkdir(backup_dir)
print(f"Папка {backup_dir} создана")
# 3. Перебор только папок в текущей директории
print("\nПапки в текущей директории:")
for item in os.listdir("."):
if os.path.isdir(item):
print(f" 📁 {item}")
# 4. Рекурсивный поиск всех поддиректорий
def find_all_directories(root_path):
"""Находит все директории в дереве каталогов"""
directories = []
for item in os.listdir(root_path):
item_path = os.path.join(root_path, item)
if os.path.isdir(item_path):
directories.append(item_path)
# Рекурсивный поиск
directories.extend(find_all_directories(item_path))
return directories
all_dirs = find_all_directories(".")
print(f"\nВсего найдено директорий: {len(all_dirs)}")
os.path.islink(path) — является ли символической ссылкой. Проверяет, является ли путь символической ссылкой (актуально для Unix-like систем).
import os.path
import os
if os.name != 'nt': # Проверяем, что не Windows
# Создаем файл и символическую ссылку
with open("target_file.txt", "w") as f:
f.write("Целевой файл")
os.symlink("target_file.txt", "symlink.txt")
# Проверяем
print(f"symlink.txt это ссылка: {os.path.islink('symlink.txt')}")
print(f"target_file.txt это ссылка: {os.path.islink('target_file.txt')}")
# Убираем за собой
os.remove("symlink.txt")
os.remove("target_file.txt")
else:
print("Символические ссылки не поддерживаются в Windows через эту функцию")
os.path.ismount(path) — является ли точкой монтирования. Проверяет, является ли путь точкой монтирования.
import os.path
# Проверка различных путей
paths_to_check = ["/", "/home", "/mnt", ".", "C:\\", "D:\\"]
print("Проверка точек монтирования:")
for path in paths_to_check:
if os.path.exists(path): # Проверяем существование перед проверкой
is_mount = os.path.ismount(path)
status = "📌 точка монтирования" if is_mount else "📂 обычный путь"
print(f" {path:20} -> {status}")
os.path.split(path) — разделяет путь на (директория, файл). Разделяет путь на кортеж (head, tail), где tail - последний компонент пути.
import os.path
# 1. Разделение пути к файлу
dir_path, file_name = os.path.split("C:/Users/Ivan/Documents/notes.txt")
print(f"Директория: {dir_path}")
print(f"Имя файла: {file_name}")
# 2. Разделение динамического пути
path = os.path.join("project", "src", "utils", "helper.py")
head, tail = os.path.split(path)
print(f"Путь: {path}")
print(f"Голова: {head}")
print(f"Хвост: {tail}")
# 3. Использование для сохранения файла в другой папке
log_path = "logs/app.log"
dir_path, file_name = os.path.split(log_path)
backup_path = os.path.join("backup", file_name)
print(f"Оригинальный путь: {log_path}")
print(f"Бэкап путь: {backup_path}")
# 4. Разделение только директории
def get_parent_directory(filepath, levels=1):
"""Получает родительскую директорию на N уровней выше"""
current = filepath
for _ in range(levels):
current = os.path.split(current)[0]
return current
parent = get_parent_directory("/home/user/project/src/main.py", levels=2)
print(f"Директория на 2 уровня выше: {parent}")
os.path.splitext(path) — разделяет имя файла и расширение. Разделяет путь на кортеж (root, ext), где ext начинается с точки.
import os.path
# 1. Разделение файла
name, ext = os.path.splitext("notes.txt")
print(f"Имя без расширения: {name}")
print(f"Расширение: {ext}")
# 2. Для изменения расширения
original = "report.docx"
name, ext = os.path.splitext(original)
new_file = name + ".pdf"
print(f"Оригинал: {original}")
print(f"Конвертирован в: {new_file}")
# 3. Проверка типа файла
def get_file_type(filename):
"""Определяет тип файла по расширению"""
name, ext = os.path.splitext(filename)
ext = ext.lower()
file_types = {
'.jpg': 'изображение',
'.jpeg': 'изображение',
'.png': 'изображение',
'.gif': 'изображение',
'.pdf': 'документ',
'.doc': 'документ Word',
'.docx': 'документ Word',
'.txt': 'текстовый файл',
'.py': 'Python скрипт',
'.zip': 'архив',
'.mp4': 'видео'
}
return file_types.get(ext, 'неизвестный тип')
test_files = ["photo.jpg", "document.pdf", "script.py", "archive.tar.gz"]
print("\nОпределение типов файлов:")
for file in test_files:
file_type = get_file_type(file)
print(f" {file:20} -> {file_type}")
# 4. Обработка файлов без расширения или с несколькими точками
test_cases = ["archive.tar.gz", "README", "config.default.json"]
print("\nСложные случаи:")
for test in test_cases:
name, ext = os.path.splitext(test)
print(f" {test:25} -> Имя: '{name}', Расширение: '{ext}'")
os.path.basename(path) — имя файла или последний компонент пути. Возвращает последний компонент пути (аналог os.path.split()[1]).
import os.path
# 1. Получение имени файла
filename = os.path.basename("/home/user/documents/report.pdf")
print(f"Имя файла: {filename}")
# 2. Для директорий тоже работает
dirname = os.path.basename("/home/user/projects/")
print(f"Имя директории: {dirname}")
# 3. Практическое использование
def process_file(filepath):
"""Обрабатывает файл, логируя его имя"""
filename = os.path.basename(filepath)
print(f"Обработка файла: {filename}")
# ... дальнейшая обработка
process_file("/var/log/app/app.log")
os.path.dirname(path) — директория пути. Возвращает директорию пути (аналог os.path.split()[0]).
import os.path
# 1. Получение директории файла
directory = os.path.dirname("/home/user/documents/report.pdf")
print(f"Директория файла: {directory}")
# 2. Вложенные вызовы для получения родительских директорий
path = "/home/user/projects/app/src/main.py"
parent1 = os.path.dirname(path)
parent2 = os.path.dirname(parent1)
parent3 = os.path.dirname(parent2)
print(f"Оригинальный путь: {path}")
print(f"Родитель 1: {parent1}")
print(f"Родитель 2: {parent2}")
print(f"Родитель 3: {parent3}")
# 3. Создание полного пути из директории и имени файла
def create_full_path(directory, filename):
"""Создает полный путь, гарантируя что directory это действительно директория"""
# Убираем возможное имя файла из directory
clean_dir = os.path.dirname(directory) if os.path.basename(directory) else directory
return os.path.join(clean_dir, filename)
full_path = create_full_path("/home/user/docs", "report.txt")
print(f"Созданный путь: {full_path}")
os.path.commonprefix(list) — общий префикс путей. Устаревшая функция (лучше использовать os.path.commonpath()).
import os.path
paths = [
"/home/user/docs/file1.txt",
"/home/user/docs/file2.txt",
"/home/user/images/photo.jpg"
]
common_prefix = os.path.commonprefix(paths)
print(f"Общий префикс: {common_prefix}")
os.path.getsize(path) — размер файла в байтах. Возвращает размер файла в байтах.
import os.path
# 1. Размер одного файла
try:
size = os.path.getsize("data.txt")
print(f"Размер data.txt: {size} байт")
except FileNotFoundError:
print("Файл data.txt не найден")
# 2. Сравнение размеров двух файлов
file1 = "a.txt"
file2 = "b.txt"
if os.path.exists(file1) and os.path.exists(file2):
size1 = os.path.getsize(file1)
size2 = os.path.getsize(file2)
if size1 > size2:
print(f"{file1} больше {file2} на {size1 - size2} байт")
elif size2 > size1:
print(f"{file2} больше {file1} на {size2 - size1} байт")
else:
print("Файлы одинакового размера")
# 3. Размер всех .txt файлов в папке
print("\nРазмеры .txt файлов:")
for f in os.listdir("."):
if f.endswith(".txt") and os.path.isfile(f):
size = os.path.getsize(f)
print(f" {f:20} {size:10} байт")
# 4. Человеко-читаемый формат размера
def human_readable_size(size_bytes):
"""Конвертирует размер в байтах в человеко-читаемый формат"""
for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
if size_bytes < 1024.0:
return f"{size_bytes:.2f} {unit}"
size_bytes /= 1024.0
return f"{size_bytes:.2f} PB"
# Тестируем
test_sizes = [100, 1024, 1048576, 1073741824]
for size in test_sizes:
readable = human_readable_size(size)
print(f"{size:15} байт = {readable}")
os.path.getatime(path) — время последнего доступ. Возвращает время последнего доступа к файлу в секундах с начала эпохи.
import os.path
import time
from datetime import datetime
# 1. Получение времени доступа
if os.path.exists("data.txt"):
access_time = os.path.getatime("data.txt")
print(f"Время последнего доступа: {access_time}")
print(f"В формате даты: {datetime.fromtimestamp(access_time)}")
# 2. Проверка, когда файл был открыт последний раз
now = time.time()
days_since_access = (now - access_time) / (24 * 3600)
print(f"Дней с последнего доступа: {days_since_access:.1f}")
os.path.getmtime(path) — время последней модификации. Возвращает время последнего изменения файла.
import os.path
import time
from datetime import datetime
# 1. Время последнего изменения
if os.path.exists("data.txt"):
modify_time = os.path.getmtime("data.txt")
print(f"Время последнего изменения: {datetime.fromtimestamp(modify_time)}")
# 2. Поиск самого нового файла в директории
def get_newest_file(directory):
files = [f for f in os.listdir(directory)
if os.path.isfile(os.path.join(directory, f))]
if not files:
return None
newest = max(files, key=lambda f: os.path.getmtime(os.path.join(directory, f)))
return newest
newest = get_newest_file(".")
if newest:
print(f"Самый новый файл: {newest}")
os.path.getctime(path) — время создания файла. Возвращает время создания файла (на Unix-системах - время изменения метаданных).
import os.path
from datetime import datetime
# Получение времени создания
if os.path.exists("data.txt"):
create_time = os.path.getctime("data.txt")
print(f"Время создания: {datetime.fromtimestamp(create_time)}")
# Сравнение времени создания и модификации
modify_time = os.path.getmtime("data.txt")
if create_time != modify_time:
print("Файл был изменен после создания")
os.path.samefile(path1, path2) — один и тот же файл? Проверяет, ссылаются ли пути на один и тот же файл (учитывает символические ссылки).
import os.path
import os
# Создаем тестовые файлы и ссылки
with open("original.txt", "w") as f:
f.write("Оригинальный файл")
# На Unix-like системах создаем жесткую ссылку
if os.name != 'nt':
os.link("original.txt", "hardlink.txt")
# Проверяем
same1 = os.path.samefile("original.txt", "hardlink.txt")
print(f"original.txt и hardlink.txt это один файл: {same1}")
# Убираем за собой
os.remove("hardlink.txt")
# Проверка разных файлов
with open("different.txt", "w") as f:
f.write("Другой файл")
same2 = os.path.samefile("original.txt", "different.txt")
print(f"original.txt и different.txt это один файл: {same2}")
# Убираем за собой
os.remove("original.txt")
os.remove("different.txt")
os.path.samestat(stat1, stat2) — одинаковая stat информация? Проверяет, ссылаются ли две stat-структуры на один и тот же файл.
import os.path
import os
if os.path.exists("test.txt"):
stat1 = os.stat("test.txt")
stat2 = os.stat("test.txt")
same = os.path.samestat(stat1, stat2)
print(f"Stat структуры указывают на один файл: {same}")
Пример 1: Создать папку backup и переместить туда все .txt файлы
import os
import os.path
import shutil
def backup_txt_files(source_dir=".", backup_dir="backup"):
"""
Создает backup папку и перемещает туда все .txt файлы
"""
# Создаем папку backup если её нет
if not os.path.exists(backup_dir):
os.makedirs(backup_dir)
print(f"Создана папка: {backup_dir}")
# Перемещаем все .txt файлы
moved_count = 0
for filename in os.listdir(source_dir):
source_path = os.path.join(source_dir, filename)
# Проверяем что это файл и имеет расширение .txt
if os.path.isfile(source_path) and filename.endswith('.txt'):
target_path = os.path.join(backup_dir, filename)
try:
# Используем shutil.move для надежного перемещения
shutil.move(source_path, target_path)
moved_count += 1
print(f"Перемещен: {filename}")
except Exception as e:
print(f"Ошибка при перемещении {filename}: {e}")
print(f"\nИтог: перемещено {moved_count} файлов")
return moved_count
# Использование
backup_txt_files()
Пример 2: Получить размер всех файлов в папке logs
import os.path
def analyze_logs_directory(logs_dir="logs"):
"""
Анализирует размер всех файлов в папке logs
"""
if not os.path.exists(logs_dir):
print(f"Папка {logs_dir} не существует")
return
if not os.path.isdir(logs_dir):
print(f"{logs_dir} не является папкой")
return
print(f"Анализ папки: {os.path.abspath(logs_dir)}")
print("=" * 50)
total_size = 0
file_count = 0
for filename in os.listdir(logs_dir):
filepath = os.path.join(logs_dir, filename)
if os.path.isfile(filepath):
size = os.path.getsize(filepath)
total_size += size
file_count += 1
# Форматированный вывод
size_str = f"{size:,}".replace(",", " ")
print(f"{filename:30} {size_str:>15} байт")
print("=" * 50)
# Статистика
if file_count > 0:
avg_size = total_size / file_count
print(f"Всего файлов: {file_count}")
print(f"Общий размер: {total_size:,} байт")
print(f"Средний размер: {avg_size:,.0f} байт")
# Человеко-читаемый формат
def human_size(size):
for unit in ['B', 'KB', 'MB', 'GB']:
if size < 1024.0:
return f"{size:.2f} {unit}"
size /= 1024.0
return f"{size:.2f} TB"
print(f"Общий размер: {human_size(total_size)}")
else:
print("В папке нет файлов")
# Использование
analyze_logs_directory()
Пример 3: Создать отчет с абсолютными путями всех файлов
import os.path
import time
def create_file_system_report(output_file="file_report.txt"):
"""
Создает подробный отчет о файловой системе
"""
with open(output_file, 'w', encoding='utf-8') as report:
# Заголовок отчета
report.write("=" * 70 + "\n")
report.write("ОТЧЕТ О ФАЙЛОВОЙ СИСТЕМЕ\n")
report.write(f"Создан: {time.strftime('%Y-%m-%d %H:%M:%S')}\n")
report.write(f"Текущая директория: {os.path.abspath('.')}\n")
report.write("=" * 70 + "\n\n")
# Статистика по типам файлов
file_extensions = {}
total_files = 0
total_dirs = 0
# Обход текущей директории
report.write("ФАЙЛЫ И ПАПКИ:\n")
report.write("-" * 70 + "\n")
for item in os.listdir("."):
item_path = os.path.join(".", item)
abs_path = os.path.abspath(item_path)
if os.path.isfile(item_path):
# Информация о файле
size = os.path.getsize(item_path)
mtime = time.ctime(os.path.getmtime(item_path))
report.write(f"[ФАЙЛ] {abs_path}\n")
report.write(f" Размер: {size:,} байт | Изменен: {mtime}\n")
# Статистика по расширениям
name, ext = os.path.splitext(item)
ext = ext.lower() if ext else "без расширения"
file_extensions[ext] = file_extensions.get(ext, 0) + 1
total_files += 1
elif os.path.isdir(item_path):
report.write(f"[ПАПКА] {abs_path}\n")
total_dirs += 1
report.write("\n" + "=" * 70 + "\n")
# Статистика
report.write("СТАТИСТИКА:\n")
report.write(f"Всего файлов: {total_files}\n")
report.write(f"Всего папок: {total_dirs}\n")
if file_extensions:
report.write("\nРАСПРЕДЕЛЕНИЕ ПО РАСШИРЕНИЯМ:\n")
sorted_exts = sorted(file_extensions.items(), key=lambda x: x[1], reverse=True)
for ext, count in sorted_exts:
percentage = (count / total_files) * 100
report.write(f" {ext:20} {count:4} файлов ({percentage:.1f}%)\n")
report.write("\n" + "=" * 70 + "\n")
report.write("КОНЕЦ ОТЧЕТА\n")
report.write("=" * 70 + "\n")
print(f"Отчет сохранен в: {os.path.abspath(output_file)}")
print(f"Найдено: {total_files} файлов, {total_dirs} папок")
# Использование
create_file_system_report()
Пример 4: Утилита для анализа размера директорий
import os.path
def analyze_directory_size(directory="."):
"""
Рекурсивно анализирует размер директории
"""
total_size = 0
file_count = 0
dir_count = 0
for dirpath, dirnames, filenames in os.walk(directory):
dir_count += len(dirnames)
for filename in filenames:
filepath = os.path.join(dirpath, filename)
try:
size = os.path.getsize(filepath)
total_size += size
file_count += 1
except OSError:
continue # Пропускаем файлы без доступа
# Результаты
print(f"Анализ директории: {os.path.abspath(directory)}")
print(f"Всего файлов: {file_count}")
print(f"Всего папок: {dir_count}")
print(f"Общий размер: {total_size:,} байт")
# Человеко-читаемый формат
size_gb = total_size / (1024**3)
size_mb = total_size / (1024**2)
if size_gb >= 1:
print(f"Общий размер: {size_gb:.2f} GB")
elif size_mb >= 1:
print(f"Общий размер: {size_mb:.2f} MB")
else:
print(f"Общий размер: {total_size / 1024:.2f} KB")
return total_size, file_count, dir_count
# Использование
analyze_directory_size()
Ключевые особенности os.path: