Так, нас просят ввести число. Давайте введем.
Нас снова просят ввести число.
Давайте, например, попросим наш интерпретатор завершить
свою работу и нажмем Ctrl + C.
Как мы видим, у нас это не получилось сделать,
то есть наша программа стала вести себя непредвиденным образом.
Она нас снова опять заставляет ввести число.
Это как раз говорит о том, что нужно обрабатывать конкретные исключения,
и в данном случае правильным вариантом данной программы была бы
обработка исключений ValueError.
Если мы попробуем снова запустить данную программу
и нажмем Ctrl--.
Давайте введем сначала неправильное число, нажмем Ctrl + C,
то возникнет исключение и его никто не обработает,
и наша программа завершит свою работу.
Поэтому не следует обрабатывать все исключения и оставлять
пустым блок except. Имейте это в виду.
Также у блока try except может быть блок else.
Блок else вызывается в том случае, если никакого исключения не произошло.
Если нам нужно обработать несколько исключений, мы можем использовать
несколько блоков except и указать разные
классы для обработки исключения.
Причем в каждом блоке except может быть свой собственный обработчик.
Например, если мы в данном примере
ввели некорректное число, то мы еще раз продолжим работу
нашего цикла.
В противном случае, если мы нажали Ctrl + C,
то мы прекратим цикл.
Именно таким образом можно обработать несколько исключений.
Если обработчик исключений выглядит одинаково,
то несколько исключений можно передать в виде списка в блок except
и также обработать сгенерированные исключения.
В данном случае
мы ожидаем два исключения, например, что пользователь ввел
некорректное число, либо если он ввел 0, то данная программа
сгенерирует ZeroDivisionError, и мы его отловим.
Мы уже с вами обсуждали классы и наследования в классах, и вот
у exception'ов есть своя иерархия, и сделана она неспроста.
Также при помощи родительского класса можно обрабатывать
несколько исключений.
Давайте, например, посмотрим на иерархию классов LookupError.
Этот класс является родительским для исключений IndexError и KeyError.
Мы можем это проверить при помощи известных нам функций issubclass.
Рассмотрим следующий пример.
У нас есть некая структура данных, это наша база данных, которая хранит
по цветам надписи на футболках.
Нам необходимо получать доступ к этим надписям по цветам.
Пользователя просим ввести цвет, просим ввести номер по порядку,
а затем обращаемся к нашей структуре данных по ключу, а затем по индексу.
И если пользователь введет, например, некорректный цвет,
то будет сгенерировано исключение KeyError,
а если пользователь введет недопустимый индекс, то будет вызвано
исключение IndexError.
Все эти исключения мы можем обработать при помощи
базового класса LookupError.
Иногда это очень удобно и требуется для как раз обработки
пользовательских исключений.