Модуль os для управления файлами в Python
Модуль os в Python предоставляет широкие возможности для взаимодействия с файловой системой. В этой статье рассматриваются основные и продвинутые приёмы работы с файлами и директориями, сопровождаемые вопросами, примерами кода и разбором частых проблем.
Основные операции с файлами через модуль os
Наиболее универсальным решением для массовой обработки файлов является комбинация os.walk для рекурсивного обхода и os.path для манипуляций с путями. Пример ниже удаляет все файлы с расширением .tmp в указанном каталоге и его подкаталогах, корректно обрабатывая ошибки доступа.
import os
root_dir = "./data"
for dirpath, dirnames, filenames in os.walk(root_dir):
for filename in filenames:
if filename.endswith(".tmp"):
full_path = os.path.join(dirpath, filename)
try:
os.remove(full_path)
print(f"Удалён: {full_path}")
except PermissionError:
print(f"Нет прав на удаление: {full_path}")
except FileNotFoundError:
print(f"Файл уже удалён: {full_path}")ввод программ на python (ввод данных в программе python)
Удалён: ./data/subdir/file1.tmp Удалён: ./data/file2.tmp Нет прав на удаление: ./data/readonly.tmp
Python file io (ввод-вывод файлов в python)
Такой подход даёт гибкость и безопасность при работе с большими деревьями папок.
Как проверить, существует ли файл или директория?
Функция os.path.exists() возвращает True, если указанный путь существует (файл или папка). Для уточнения типа объекта используют os.path.isfile() и os.path.isdir().
path = "./test.txt"
if os.path.exists(path):
print(f"{path} существует")
if os.path.isfile(path):
print("Это файл")
elif os.path.isdir(path):
print("Это директория")
else:
print(f"{path} не найден")Python temp files (временные файлы в python)
./test.txt существует Это файл
Python index files (индексация файлов в python)
Типичная ошибка: вызов os.path.exists() для символической ссылки, ведущей к несуществующему объекту, возвращает False. Используйте os.path.lexists(), если нужно проверить саму ссылку.
Цель: безопасное выполнение последующих операций над файлом. Используется перед удалением, чтением или созданием.
Как удалить файл или пустую директорию?
Для удаления файла вызывают os.remove() или os.unlink() (синонимы). Пустую папку удаляют с помощью os.rmdir(). Непустую директорию предварительно нужно очистить (обычно через shutil.rmtree()).
import os
try:
os.remove("./old_data.txt")
os.rmdir("./empty_dir")
print("Удаление успешно")
except FileNotFoundError:
print("Объект не найден")
except PermissionError:
print("Нет прав")
except OSError as e:
print(f"Ошибка: {e}")File python class (класс для работы с файлами в python)
Удаление успешно
Python file utf 8 (кодировка utf-8 для файлов в python)
Типичная ошибка: попытка удалить непустую директорию через os.rmdir() вызывает OSError с сообщением “Directory not empty”.
Как переименовать или переместить файл?
Функция os.rename() перемещает или переименовывает файл/папку. Если целевой файл уже существует, на некоторых системах возникнет ошибка. os.replace() атомарно заменяет целевой файл новым.
os.rename("./old.txt", "./new.txt")
os.replace("./data.txt", "./backup/data.txt")Python config files (конфигурационные файлы в python)
(без вывода, если успешно)
Python copy file (копирование файла в python)
Проблема: при перемещении между разными файловыми системами os.rename() может не сработать (возвращает Cross-device link). Решение - использовать shutil.move().
Как получить информацию о файле (размер, время)?
os.stat() возвращает объект stat_result с данными: размер (st_size), время последней модификации (st_mtime), права доступа и др. Для быстрой справки есть функции-обёртки os.path.getsize() и os.path.getmtime().
import time
file_info = os.stat("./example.txt")
print(f"Размер: {file_info.st_size} байт")
mtime = time.ctime(file_info.st_mtime)
print(f"Последнее изменение: {mtime}")Python log file (логирование в файл в python)
Размер: 4096 байт Последнее изменение: Tue Jan 14 10:30:00 2025
Python file methods (методы работы с файлами в python)
Ошибка: если файл не существует, os.stat() выбрасывает FileNotFoundError.
Как обойти все файлы и поддиректории рекурсивно?
os.walk() генерирует кортежи (dirpath, dirnames, filenames) для каждого каталога в дереве. Можно фильтровать dirnames, чтобы исключить определённые папки.
for root, dirs, files in os.walk("."):
# Исключить скрытые папки
dirs[:] = [d for d in dirs if not d.startswith(".")]
for f in files:
if f.endswith(".log"):
print(os.path.join(root, f))File models in python (модели файлов в python)
./app/logs/error.log ./app/logs/debug.log
File handle python (обработка файлов в python)
Проблема доступа: os.walk() может вызвать PermissionError при попытке зайти в защищённые папки. Используйте параметр onerror.
def handle_error(instance):
print(f"Ошибка доступа: {instance.filename}")
for root, dirs, files in os.walk(".", onerror=handle_error):
passPython open file read (открытие файла для чтения в python)
Как создать и удалить директории?
os.mkdir() создаёт один каталог, os.makedirs() рекурсивно создаёт все промежуточные папки. Удаление - os.rmdir() для пустой, os.removedirs() для очистки вложенных пустых каталогов.
os.makedirs("./path/to/new/folder", exist_ok=True)
os.rmdir("./empty")
os.removedirs("./a/b/c") # удалит c, потом b, потом a, если они пустыPython file position (позиционирование в файле python)
Цель: подготовка структуры для сохранения файлов.
Как работать с путями (склеивание, разделение, абсолютный путь)?
os.path.join() корректно объединяет части пути с учётом разделителя ОС. os.path.split() делит путь на голову и хвост. os.path.abspath() возвращает абсолютный путь.
parts = ["folder", "sub", "file.txt"]
full = os.path.join(*parts)
print(full)
head, tail = os.path.split(full)
print(f"Голова: {head}, Хвост: {tail}")
abs_path = os.path.abspath("file.txt")
print(abs_path)Python line find (поиск строки в файле python)
folder/sub/file.txt Голова: folder/sub, Хвост: file.txt /home/user/project/file.txt
Python csv file (работа с csv файлами в python)
Частая ошибка: использование конкатенации строк (path + "/" + filename) приводит к проблемам с обратной косой чертой на Windows.
Как изменить права доступа к файлу или владельца?
os.chmod() устанавливает права (режим доступа) в восьмеричном виде или через константы из stat. os.chown() меняет владельца (требуются права суперпользователя).
os.chmod("private.txt", 0o600) # только владелец чтение/запись
import stat
os.chmod("script.py", stat.S_IRWXU | stat.S_IRGRP) # владельцу всё, группе чтениеPython работа с данными файла (работа с данными из файла в python)
Ошибка PermissionError: недостаточно прав для изменения атрибутов защищённой системы.
Как работать с символическими ссылками?
os.symlink() создаёт символическую ссылку, os.readlink() читает её цель, os.path.islink() проверяет, является ли путь ссылкой.
os.symlink("./real_file.txt", "./link.txt")
if os.path.islink("./link.txt"):
target = os.readlink("./link.txt")
print(f"Ссылка ведёт на {target}")Key files python (работа с ключевыми файлами в python)
Ссылка ведёт на ./real_file.txt
На Windows создание символических ссылок может требовать прав администратора или включённого режима разработчика.
import os
import time
# 1. Рекурсивный подсчёт суммарного размера файлов с расширением .py
def total_size_by_extension(root_dir, ext):
total = 0
count = 0
for dirpath, _, filenames in os.walk(root_dir):
for f in filenames:
if f.endswith(ext):
file_path = os.path.join(dirpath, f)
try:
total += os.path.getsize(file_path)
count += 1
except (FileNotFoundError, PermissionError):
continue
return total, count
size, num = total_size_by_extension("./src", ".py")
print(f"Найдено {num} файлов .py, общий размер {size} байт")
# Результат:
# Найдено 12 файлов .py, общий размер 45728 байт
Найдено 12 файлов .py, общий размер 45728 байт
# 2. Пакетное переименование: добавление суффикса "_backup" к файлам .txt
def rename_txt_with_backup(root_dir):
for dirpath, _, filenames in os.walk(root_dir):
for f in filenames:
if f.endswith(".txt"):
old = os.path.join(dirpath, f)
name, ext = os.path.splitext(f)
new = os.path.join(dirpath, name + "_backup" + ext)
try:
os.rename(old, new)
print(f"{old} -> {new}")
except OSError as e:
print(f"Не удалось переименовать {old}: {e}")
rename_txt_with_backup("./documents")
./documents/report.txt -> ./documents/report_backup.txt ./documents/notes.txt -> ./documents/notes_backup.txt
# 3. Использование os.scandir() для эффективного получения атрибутов
with os.scandir("./data") as entries:
for entry in entries:
if entry.is_file():
info = entry.stat()
print(f"{entry.name}: {info.st_size} байт, изменён {time.ctime(info.st_mtime)}")
config.json: 2048 байт, изменён Mon Jan 13 15:45:12 2025 log.txt: 102400 байт, изменён Tue Jan 14 09:12:33 2025
# 4. Мониторинг изменений в директории (проверка времени модификации)
def get_mtime(path):
return os.path.getmtime(path) if os.path.exists(path) else 0
prev_state = {}
watch_dir = "./watch"
while True:
for f in os.listdir(watch_dir):
full = os.path.join(watch_dir, f)
if os.path.isfile(full):
mtime = get_mtime(full)
if f in prev_state:
if mtime != prev_state[f]:
print(f"Файл изменён: {f}")
else:
print(f"Новый файл: {f}")
prev_state[f] = mtime
time.sleep(5)
break # для примера один проход
Новый файл: data.txt Файл изменён: data.txt