tariel.ge › Полезное: бесплатные книги › Программирование: от нулей и единиц до PythonБесплатно · автор Тариел Бежанидзе
← Учебник по программированию ЛИСТ 21БЛОК 4 — PYTHON НА ПРАКТИКЕРЕВ. 1
Глава 21 · Python на практике

Обработка ошибок и чтение сообщений об ошибках

Прямое практическое продолжение честного разговора из главы 05: интерпретируемый язык обнаруживает многие ошибки только в момент выполнения конкретной строки — здесь про то, как реагировать на это осознанно, а не наблюдать, как программа просто падает.

Исключение — объект-сигнал о том, что пошло не так

Когда в Python что-то идёт не так во время выполнения, поднимается исключение (exception) — объект, описывающий конкретную проблему. Если его никто не перехватывает, оно "поднимается" вверх по цепочке вызовов функций и в итоге аварийно останавливает программу, печатая сообщение об ошибке (traceback, разбирается ниже).

try/except — перехват ошибки

try:
    number = int(input("Введите число: "))
    print(f"Квадрат: {number ** 2}")
except ValueError:
    print("Это не похоже на число")

Код внутри try выполняется как обычно; если внутри него возникает исключение указанного типа, выполнение сразу переходит в блок except, а не аварийно останавливает всю программу.

Частые типы исключений — уже встречались раньше в этой книге

ИсключениеКогда возникает
ValueErrorЗначение не подходит по смыслу — например, int("abc") из главы 14
TypeErrorОперация применена к несовместимым типам — например, попытка сложить строку и число напрямую (глава 14)
FileNotFoundErrorПопытка открыть несуществующий файл (глава 19)
ZeroDivisionErrorДеление на ноль
IndexErrorИндекс списка за пределами его длины (глава 17)
KeyErrorОбращение к несуществующему ключу словаря (глава 17)
UnicodeDecodeErrorНесовпадение реальной и указанной кодировки файла (главы 03, 18, 19)

Почему не стоит перехватывать "всё подряд"

Голый except — плохая практика

Конструкция except: без указания конкретного типа перехватывает буквально любое исключение — включая те, которые на самом деле стоило бы заметить и исправить, а не молча проглотить. Это маскирует настоящие ошибки в коде, выдавая видимость "программа работает", хотя на деле она просто скрывает проблему. Указывай конкретный тип исключения, который действительно ожидаешь и умеешь корректно обработать.

else и finally

try:
    f = open("data.txt", encoding="utf-8")
except FileNotFoundError:
    print("Файл не найден")
else:
    print("Файл успешно открыт") # выполняется только если ошибки не было
    f.close()
finally:
    print("Попытка завершена") # выполняется всегда, независимо от результата

else выполняется только при отсутствии исключения, finally — всегда, независимо от того, было исключение или нет — удобно для гарантированной "уборки" (например, закрытия ресурса), хотя для файлов, как уже говорилось в главе 19, эту роль чаще берёт на себя with.

Собственные исключения через raise

def set_age(age):
    if age < 0:
        raise ValueError("Возраст не может быть отрицательным")
    return age

Собственная функция может сознательно "поднять" исключение, если получила данные, с которыми не может корректно работать — явный сигнал вызывающему коду о проблеме, вместо молчаливого продолжения работы с некорректными данными. Более сложные проекты иногда определяют собственные классы исключений (тема пересекается с главой 24 про классы) — для задач этой книги достаточно поднимать уже существующие подходящие по смыслу типы вроде ValueError.

Как читать traceback — реальный пример

Traceback (most recent call last):
  File "script.py", line 7, in <module>
    result = divide(10, 0)
  File "script.py", line 3, in divide
    return a / b
ZeroDivisionError: division by zero
Читай снизу вверх

Самая важная информация — в самом низу: тип исключения и сообщение (ZeroDivisionError: division by zero). Выше — цепочка вызовов, приведшая к этой ошибке, начиная с самого раннего вызова наверху и заканчивая точным местом, где ошибка реально произошла, ближе к низу. В этом примере видно: строка 7 вызвала функцию divide, а уже внутри неё, на строке 3, произошло деление на ноль. Умение быстро находить в этом стеке именно свою строку кода (а не строку внутри стандартной библиотеки или сторонней библиотеки) — практический навык, который приходит с опытом чтения таких сообщений.

Практический пример: устойчивое чтение пользовательского ввода

while True:
    try:
        age = int(input("Возраст: "))
        break # успешно получили число — выходим из цикла
    except ValueError:
        print("Пожалуйста, введите число") # и цикл повторится снова

Что дальше

Следующая глава — файловая система из Python напрямую (os, pathlib): прямое практическое продолжение и терминальных команд блока 2, и темы файлов из главы 19, теперь уже без выхода в терминал вообще, а изнутри самого кода.

Глава21 — Обработка ошибок
Блок4 — Python на практике
Далее22 — Файловая система из Python
СтатусГотово · рев. 1
Предыдущая глава ← 20 · Модули, пакеты, pip Следующая глава 22 · Файловая система из Python →

Книга бесплатна для чтения. Автор — Тариел Бежанидзе, компьютерный мастер в Батуми · tariel.ge · все бесплатные книги. Копировать текст целиком на другие сайты — только со ссылкой на источник.