Глава 15 · Python и файлы
Ошибки файловой системы
Файловые операции обращаются к внешнему миру — и внешний мир не всегда отвечает так, как хочется.
Частые ошибки файловой системы
| Исключение | Когда возникает |
|---|---|
FileNotFoundError | путь не существует, а операция ожидала существующий файл |
FileExistsError | режим "x" (или похожая операция) — а файл уже есть |
PermissionError | нет прав на чтение/запись этого пути |
IsADirectoryError | путь — папка, а операция ожидала файл |
NotADirectoryError | путь — файл, а операция ожидала папку |
UnicodeDecodeError | байты не удаётся декодировать выбранной кодировкой (15.16) |
Общий предок — OSError
Большинство файловых исключений — это разновидности
OSError. Знать всю иерархию классов исключений не обязательно — достаточно уверенно распознавать перечисленные выше по имени и понимать, когда каждое из них возникает.Чек-лист: файл не найден
- Что сейчас является CWD? (
Path.cwd(), раздел 15.7) - Какой именно путь был построен в коде?
- Существует ли родительская папка этого пути?
- Нет ли опечатки в имени?
- Путь абсолютный или относительный — и относительно чего?
- Совпадает ли регистр букв в имени файла?
Регистр имени файла — не мелочь
Поведение по чувствительности к регистру различается между файловыми системами. Не считайте, что
Data.txt и data.txt — обязательно один и тот же файл: пишите код так, чтобы имя совпадало точно.Debug Lab 11: Открыли папку как файл
papka_kak_fajl.py
from pathlib import Path
Path("arhiv").mkdir(exist_ok=True)
with open("arhiv", "r", encoding="utf-8") as f: # "arhiv" — это папка!
print(f.read())
Traceback (most recent call last):
IsADirectoryError: [Errno 21] Is a directory: 'arhiv'
"arhiv" — папка, а не файл, и её нельзя открыть как файл для чтения текста. Перед открытием стоило проверить .is_file().
Исправленный код
proverka_pered_otkrytiem.py
from pathlib import Path
path = Path("arhiv")
if path.is_file():
with path.open("r", encoding="utf-8") as f:
print(f.read())
else:
print(f"{path} — не обычный файл")
Обрабатываем именно ту ошибку, которую ожидаем
targeted_except.py
from pathlib import Path
path = Path("nastroyki.json")
try:
text = path.read_text(encoding="utf-8")
except FileNotFoundError:
print("Файл настроек не найден — используем значения по умолчанию")
text = "{}"
Никогда except: pass
Пустой перехват всех исключений подряд молча прячет реальные проблемы программы. Ловите конкретное ожидаемое исключение — как
FileNotFoundError выше — а не всё подряд.Чуть глубже: EAFP и LBYL
Два стиля: проверить заранее (if path.exists():)
или попробовать и обработать ошибку (try/except).
В Python операции с файлами часто пишут вторым способом — именно потому, что состояние
файловой системы может измениться между проверкой и самой операцией (раздел 15.19). Запоминать
сами английские сокращения не обязательно — важна идея.
Практика: ошибки файловой системы
Интерактивный ноутбук прямо в браузере — Python 3.14 через Pyodide, без установки