📖 Теория: Summary session 13

⚡ Кратко

Исключения — это события, которые прерывают выполнение программы при ошибке. Их можно перехватить и обработать.

Базовая конструкция — try/except. Обработчики проверяются сверху вниз, общий Exception ставят последним.

else выполняется при успехе, finally — всегда. raise возбуждает исключение, logging записывает его в файл.

Модуль os даёт функции для работы с файловой системой: getcwd, listdir, path.join, walk. Модуль sys предоставляет argv — аргументы командной строки.

Исключения: повторение

Исключение — это объект, который Python создаёт, когда возникает ошибочная ситуация. Если исключение не обработать, программа завершается и выводит traceback — трассировку с указанием типа ошибки, сообщения и места.

# zero_division_demo.py
print(10 / 0)  # ZeroDivisionError: division by zero

Обработка исключений позволяет перехватить ошибку и продолжить выполнение.

Частые встроенные исключения

ИсключениеПричинаПример
ZeroDivisionErrorДеление на ноль10 / 0
ValueErrorНекорректное значениеint("abc")
KeyErrorНесуществующий ключ словаряinfo = {"a": 1}; info["b"]
IndexErrorИндекс вне диапазона[1, 2][10]
TypeErrorНеправильный тип"2" + 2
FileNotFoundErrorФайл не найденopen("missing.txt")

Конструкция try/except

В блок try помещают код, который может вызвать исключение. В блок except — обработчик конкретного типа ошибки.

# safe_divide.py
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Ошибка: деление на ноль!")

print("Программа продолжает работу")

Важные правила:

  • В try оставляют только код, который может вызвать исключение.
  • Обработчики проверяются сверху вниз; первый подходящий сработает.
  • Общий except Exception: всегда ставят последним.

Блоки else и finally

else выполняется, если в try не возникло исключения. finally выполняется всегда — удобно для завершающих действий.

# full_structure.py
try:
    number = int(input("Введите число: "))
    result = 10 / number
except ValueError:
    print("Некорректное значение.")
except ZeroDivisionError:
    print("Деление на ноль.")
else:
    print(f"Результат: {result}")
finally:
    print("Программа завершена.")

Возбуждение исключений через raise

Ключевое слово raise позволяет сообщить об ошибке явно:

# raise_demo.py
number = -1
if number < 0:
    raise ValueError("Число не может быть отрицательным")

После raise программа остановится, если исключение не перехватить:

# raise_with_except.py
while True:
    try:
        number = int(input("Введите положительное число: "))
        if number < 0:
            raise ValueError("Число не может быть отрицательным")
        print(f"Вы ввели: {number}")
        break
    except ValueError as e:
        print(f"Ошибка: {e}. Попробуйте снова.")

Логирование ошибок

Модуль logging записывает сообщения разного уровня важности. По умолчанию выводятся только сообщения уровня WARNING и выше.

УровеньМетодОписание
DEBUGlogging.debugОтладочные сообщения
INFOlogging.infoОбщая информация
WARNINGlogging.warningПредупреждения
ERRORlogging.errorОшибки
CRITICALlogging.criticalКритические ошибки
# logging_demo.py
import logging

logging.basicConfig(filename="app.log", level=logging.INFO)
logging.info("Программа запущена")
logging.warning("Низкий уровень памяти")
logging.error("Ошибка подключения")

Файловая система: пути

Абсолютный путь начинается от корневой директории и однозначно указывает на объект.

# absolute_paths.py
linux_path = "/home/user/documents/file.txt"
windows_path = "C:\\Users\\User\\Documents\\file.txt"

Относительный путь указывается от текущей рабочей директории.

# relative_paths.py
./file.txt      # файл в текущей директории
../file.txt     # файл в родительской директории
../../file.txt  # на два уровня выше
СимволЗначение
.Текущая директория
..Родительская директория
/Разделитель в Linux/macOS
\\Разделитель в Windows
~Домашняя директория (Linux/macOS)

Модуль os

Модуль os предоставляет инструменты для работы с операционной системой и файловой системой.

# os_demo.py
import os

print(os.getcwd())                       # текущая директория
print(os.listdir("."))                   # содержимое текущей директории
print(os.path.exists("example.txt"))     # проверка существования
print(os.path.isfile("example.txt"))     # это файл?
print(os.path.isdir("example_folder"))   # это папка?
print(os.path.abspath("example.txt"))    # абсолютный путь
print(os.path.basename("/a/b/file.txt")) # имя файла
print(os.path.dirname("/a/b/file.txt"))  # директория
print(os.path.join("folder", "file.txt")) # соединение путей

os.makedirs("parent/child", exist_ok=True)  # вложенные папки

Для рекурсивного обхода директории используют os.walk:

# os_walk_demo.py
import os

for root, dirs, files in os.walk("."):
    print(f"Директория: {root}")
    print(f"  Папки: {dirs}")
    print(f"  Файлы: {files}")

Модуль sys и аргументы командной строки

Модуль sys даёт доступ к параметрам интерпретатора. sys.argv — список аргументов командной строки, где первый элемент — имя скрипта.

# sys_argv_demo.py
import sys

print("Все аргументы:", sys.argv)

if len(sys.argv) > 1:
    print(f"Первый аргумент: {sys.argv[1]}")
else:
    print("Аргументы не переданы.")

Лучшие практики

  • Ловите конкретные исключения, а не всё подряд.
  • Минимизируйте код в блоке try.
  • Используйте finally или менеджеры контекста для освобождения ресурсов.
  • Не подавляйте ошибки пустым pass — логируйте их.
  • Для путей используйте os.path.join, а не ручную склейку строк.
⚠️ Проверить по документации: для работы с файлами в современном Python рекомендуется использовать менеджер контекста with. Он автоматически закрывает файл даже при исключении. Модуль pathlib также не входит в исходную лекцию, но является современной альтернативой os.path.

Краткий итог

Исключения помогают программе не падать от любой ошибки, а файловая система — хранить и обрабатывать данные на диске. Грамотный код сочетает конкретную обработку ошибок, логирование и корректную работу с путями через os и sys.