Блог

Исключения в Python. Введение

Python Exception Handling. Introduction

Не ошибается только тот, кто ничего не делает. Поэтому ошибки в коде — естественны и неизбежны.

Однако ошибка ошибке рознь. Есть обычные опечатки, которые сразу же обнаружит и подчеркнёт редактор IDE, либо выявит сам интерпретатор при первом же прогоне. Но есть ошибки, заметить которые не так просто. Которые обязательно дождутся самого неподходящего момента и громко дадут о себе знать.

В первом случае это Syntax Errors (синтаксические ошибки), а во втором — Exceptions (исключения).

Синтаксическая ошибка — это ошибка в синтаксисе последовательности символов или токенов. Иными словами, синтаксическая ошибка — это несоответствие правилам записи кода, без исправления которой код не может быть запущен.

Исключения возникают, если программа синтаксически верна, но в некоторых случаях (при некоторых значениях переменных) исполнение кода приводит к ошибке. То есть исключения возникают в тех случаях, когда программист не учёл или не предусмотрел какое-либо событие, которое в итоге привело в ошибке и остановке программы.

Классический пример — ошибка деления на 0:

>>> 5 / 0
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    ZeroDivisionError: division by zero

Главное, что всегда следует знать программисту при появлении сообщения об ошибке:

  • так это причину, её вызвавшую,
  • а также место в коде, где она появилась.
И, как видно из примера выше, интерпретатор Python уже имеет в своём арсенале встроенную систему классификацию таких ошибок, благодаря чему мы знаем:

  1. Место возникновения ошибки (строка #1 файла “стандартный ввод” File "", line 1, in <module>);
  2. Класс ошибки (деление на ноль — ZeroDivisionError);
  3. И даже подробную характеристику этого класса (division by zero)

Всё это так — “сервис исключений” (если его можно так назвать) в Python, позволяет эффективно бороться с ошибками после остановки программы. А может ли он помочь ещё до остановки программы, в процессе её выполнения?

Давайте рассмотрим пример. Предположим, в бесконечном цикле пользователь должен вводить значение делителя и получать: либо результат деления на введённое число (при правильном вводе), либо сообщение, что введённое число даст ошибку и просьбу ввести вместо него правильный вариант.

while True
    line = input('Please enter an integer: ')
    if line == 'end':
        break

    if line == '0':
        print('Zero gives an error! Please enter a different number!')
           continue

    result = 100 / int(line)
    print(result)

Программа будет работать до тех пор, пока пользователь не введёт end.

В этом примере учтена возможность ввода пользователем нулевого значения. Для этого каждое введённое значение прежде сравнивается с нулём. И если пользователь ввёл 0, то программа его не примет и попросит ввести другое значение.

Это действительно решает проблему. Но что будет, если число окажется дробным? А если пользователь по ошибке введёт букву и другой символ? В этом случае всё равно будет аварийное завершение программы. Мы конечно же может предусмотреть и эти два варианта ошибочного ввода и поставить точно такие же “заглушки” как и в случае ввода число 0. Но где гарантия, что не может возникнуть других ошибок ввода помимо этих трёх?

Один из вариантов решения — не сравнивать введённый результат со списком ошибочных значений, а сразу же обработать все возможные исключений с помощью конструкции try-except (переход на эту статью по ссылке ниже).

Исключения в Python. Конструкция try-except

Конструкция try-except — далеко не единственный способ использования исключений в Python. Более подробно этот вопрос рассмотриваются в следующих статьях:

Исключения в Python. Конструкция try-except-else

Исключения в Python. Конструкция try-except-finally

Исключения в Python. Перехват специфических ошибок

Исключения в Python. Операторы вызова исключений raise и assert