Исключения — это конструкции, которые позволяют отлавливать ошибку выполнения кода.
Во время написания программы допускаются ошибки, порой нелепые, а порой рушащие всю программу. Вообще ошибки можно разложить на две категории: логические и фактические.
Логическая ошибка — это ошибка в алгоритме. Не тот знак сравнения, переприсвоение уже существующей переменной, не то количество проходов цикла, отсутствие счётчика цикла, и тому подобное. Главная особенность этой ошибки, что её отследить довольно таки сложно, так как нужно искать «руками».
Фактическая ошибка — это такая ошибка, которая очень очевидна. Деление на ноль, переполнение массива, выход за границу массива, обращение к несуществующему элементу, и так далее. На такой сорт ошибок нам укажет сам интерпретатор.
Когда мы пытаемся поделить некое число, которое больше нуля, на ноль, у нас возникает ошибка.
1 2 3 4 5 6 7 |
a = 1 / 0 print('ХАХАХАХ') Traceback (most recent call last): File "C:/Users/Эккерт Николай/Desktop/fd.py", line 1, in <module> a = 1 / 0 ZeroDivisionError: division by zero |
Заметьте, функция вывода не сработала.
Самая нижняя строчка «ZeroDivisionError» — это имя ошибка, через двоеточие идёт её описание.
Таким методом интерпретатор сообщает нам о множестве фактических ошибок.
Главная беда в том, что после возникновения такой ошибки наша программа «падает», происходит аварийное завершение программы и весь код, который находится после кода с ошибкой, не срабатывает.
Произошла фактическая ошибка -> интерпретатор выдал ошибку -> завершение программы
Вот такая не замысловатая схема.
Но такой вариант нам не подходит, нам нужно, чтобы программа сработала вся. И тут нам поможет обработка исключений!
Три ключевых слова будут нашим спасением:
- try — блок «ловушка», в него помещается код, в котором может произойти ошибка;
- except — блок «фильтр», в него помещается имя ошибки и код, который должен быть выполнен в случае возникновения этой ошибки. На одну «ловушку» может быть сколько угодно «фильтров»;
- finally — блок «пропуск», в который помещается код, который должен быть выполнен независимо «фильтров». На одну «ловушку» может быть только один «пропуск»;
Соберём всё вместе:
- В «ловушку» помещается код, в котором может возникнуть ошибка;
- К «ловушке» привязываются «фильтры» с кодом, который выполнится в случае возникновения именно этой ошибки;
- По желанию можно создать блок «пропуска» с неким кодом, который будет выполняться независимо от того были ошибки или нет;
Разберём тот же пример с делением на ноль.
1 2 3 4 5 6 7 8 |
try: #блок "ловушка" a = 1 / 0 #в переменную помещаем результат деления (возникает ошибка) except ZeroDivisionError: #блок "фильтр" с указанием имени ошибки print('Деление на ноль!') #код, который выполняется при возникновении соответствующей ошибки finally: #блок "пропуск" print('Блок "ловушка" сработал!') #код, который выполняется в любом случае print('ХАХАХАХ') #вывод сообщения |
Мы поделили на ноль, но при этом вывели сообщение «ХАХАХАХ».
Можно не указывать имя ошибки и тогда будут обрабатываться ВСЕ ошибки, но это не является хорошим тоном программирования, нельзя понять какая именно ошибка произошла в программе. Но порой, это лучшее решение.
1 2 3 4 5 6 7 8 |
try: #блок "ловушка" a = 1 / 0 #в переменную помещаем результат деления (возникает ошибка) except: #блок "фильтр" без указания имени ошибки print('Деление на ноль!') #код, который выполняется при возникновении любой ошибки finally: #блок "пропуск" print('Блок "ловушка" сработал!') #код, который выполняется в любом случае print('ХАХАХАХ') #вывод сообщения |
Таким нехитрым образом мы разобрались с «исключения в Python«!