Исключения (Exceptions) Python
Исключения (exceptions)
— ещё один тип данных в python. Исключения необходимы для того, чтобы сообщать программисту об ошибках. Самый простой пример исключения — деление на ноль. Если попробовать запустить такую программу
z = 100 / 0
она завершится с ошибкой
Traceback (most recent call last):
File "", line 1, in
ZeroDivisionError: division by zero
ZeroDivisionError
— это название исключения, а division by zero
— его краткое описание. Также Python сообщит номер строки, где это исключение возникло.
Разумеется, возможны и другие исключения. Например, при попытке сложить строку и число
z = 2 + '1'
произойдет исключение TypeError
Traceback (most recent call last):
File "", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'
В этом примере генерируется исключение TypeError
. Подсказки дают нам полную информацию о том, где порождено исключение, и с чем оно связано.
Рассмотрим иерархию встроенных в python исключений, хотя иногда вам могут встретиться и другие, так как программисты могут создавать собственные исключения.
BaseException
— базовое исключение, от которого берут начало все остальные.SystemExit
— исключение, порождаемое функциейsys.exit
при выходе из программы.KeyboardInterrupt
— порождается при прерывании программы пользователем (обычно сочетанием клавиш Ctrl+C).GeneratorExit
— порождается при вызове метода close объекта generator.Exception
— а вот тут уже заканчиваются полностью системные исключения (их лучше не трогать) и начинаются обыкновенные, с которыми можно работать.StopIteration
— порождается встроенной функциейnext
, если в итераторе больше нет элементов.ArithmeticError
— арифметическая ошибка.FloatingPointError
— порождается при неудачном выполнении операции с плавающей запятой. На практике встречается нечасто.OverflowError
— возникает, когда результат арифметической операции слишком велик для представления. Не появляется при обычной работе с целыми числами (так как python поддерживает длинные числа), но может возникать в некоторых других случаях.ZeroDivisionError
— деление на ноль.AssertionError
— выражение в функцииassert
ложно.AttributeError
— объект не имеет данного атрибута (значения или метода).BufferError
— операция, связанная с буфером, не может быть выполнена.EOFError
— функция наткнулась на конец файла и не смогла прочитать то, что хотела.ImportErrorс
— не удалось импортирование модуля или его атрибута.LookupError
— некорректный индекс или ключ.IndexError
— индекс не входит в диапазон элементов.KeyError
— несуществующий ключ (в словаре, множестве или другом объекте).MemoryError
— недостаточно памяти.NameError
— не найдено переменной с таким именем.UnboundLocalError
— сделана ссылка на локальную переменную в функции, но переменная не определена ранее.OSError
— ошибка, связанная с системой.BlockingIOError
ChildProcessError
— неудача при операции с дочерним процессом.ConnectionError
— базовый класс для исключений, связанных с подключениями.BrokenPipeError
ConnectionAbortedError
ConnectionRefusedError
ConnectionResetError
FileExistsError
— попытка создания файла или директории, которая уже существует.FileNotFoundError
— файл или директория не существует.InterruptedError
— системный вызов прерван входящим сигналом.IsADirectoryError
— ожидался файл, но это директория.NotADirectoryError
— ожидалась директория, но это файл.PermissionError
— не хватает прав доступа.ProcessLookupError
— указанного процесса не существует.TimeoutError
— закончилось время ожидания.ReferenceError
— попытка доступа к атрибуту со слабой ссылкой.RuntimeError
— возникает, когда исключение не попадает ни под одну из других категорий.NotImplementedError
— возникает, когда абстрактные методы класса требуют переопределения в дочерних классах.SyntaxError
— синтаксическая ошибка.IndentationError
— неправильные отступы.TabError
— смешивание в отступах табуляции и пробелов.SystemError
— внутренняя ошибка.TypeError
— операция применена к объекту несоответствующего типа.ValueError
— функция получает аргумент правильного типа, но некорректного значения.UnicodeError
— ошибка, связанная с кодированием / раскодированиемunicode
в строках.UnicodeEncodeError
— исключение, связанное с кодированиемunicode
.UnicodeDecodeError
— исключение, связанное с декодированиемunicode
.UnicodeTranslateError
— исключение, связанное с переводомunicode
.Warning
— Базовый класс для исключений-предупреждений. Данное семейство исключений представляет собой различные категории предупреждений.BYTESWARNING
— Предупреждения, связанные с возможными проблемами при работе с байтами. Данная категория предупреждений используется в случаях возможных ошибок при работе с бйтами (bytes и bytearray).DeprecationWarning
— Категория предупреждений о функциональности нежелательной к использованию. Эту категорию обычно используют для указания на то, что некая часть функциональности морально устарела (возможно ей на смену пришла более совершенная) и не рекомендуется к использованию.FUTUREWARNING
— Категория, описывающая предупреждения об изменениях в будущем. Предупреждения данной категории призваны оповещать о грядущих семантических изменениях. Пример предупреждения о грядущих изменениях из numpy:FutureWarning: comparison to 'None' will result in an elementwise object comparison in the future.IMPORTWARNING
— предупреждение о вероятной ошибке при импорте модуля. Предупреждения данной категории могут использоваться, например, в случаях внесения изменений в систему импорта при помощи перехватчиков (хуков).PendingDeprecationWarning
— Категория предупреждений о функциональности, которая вскоре должна стать нежелательной к использованию.ResourceWarning
— Предупреждения, связанные с возможными проблемами при работе с ресурсами. Примером использования данной категории предупреждений можут служить указание на необходимость закрытия сокета, что необходимо для высвобождения ресурсов.RuntimeWarning
— Предупреждение о сомнительном поведении во время исполнения. Категория может быть использована для обозначения сомнительного поведения приложения, например, если код выявил вероятные погрешности в вычислениях.SyntaxWarning
— Предупреждение об использовании сомнительных синтаксических конструкций. Категория используется в случаях, когда замечены вероятные синтаксические ошибки.UnicodeWarning
— Предупреждения, связанные с возможными проблемами при работе с Юникод.USERWARNING
— Класс для пользовательских предупреждений. Может использоваться пользователями в качестве базового класса для создания собственных иерархий предупреждений.
Теперь, зная, когда и при каких обстоятельствах могут возникнуть исключения, мы можем их обрабатывать. Для обработки исключений используется конструкция try — except
.
Первый пример применения этой конструкции:
try:
k = 1 / 0
except ZeroDivisionError:
k = 0
print(k)
0
В блоке try
мы выполняем инструкцию, которая может породить исключение, а в блоке except
мы перехватываем их. При этом перехватываются как само исключение, так и его потомки. Например, перехватывая ArithmeticError
, мы также перехватываем FloatingPointError
, OverflowError
и ZeroDivisionError
.
try:
k = 1 / 0
except ArithmeticError:
k = 0
print(k)
0
Также возможна инструкция except
без аргументов, которая перехватывает вообще всё (и прерывание с клавиатуры, и системный выход и т. д.). Поэтому в такой форме инструкция except
практически не используется, а используется except Exception
. Однако чаще всего перехватывают исключения по одному, для упрощения отладки (вдруг вы ещё другую ошибку сделаете, а except
её перехватит).
Ещё две инструкции, относящиеся к нашей проблеме, это finally
и else
. Finally
выполняет блок инструкций в любом случае, было ли исключение, или нет (применима, когда нужно непременно что‑то сделать, к примеру, закрыть файл). Инструкция else
выполняется в том случае, если исключения не было.
f = open('1.txt')
ints = []
try:
for line in f:
ints.append(int(line))
except ValueError:
print('Это не число. Выходим.')
except Exception:
print('Это что ещё такое?')
else:
print('Всё хорошо.')
finally:
f.close()
print('Я закрыл файл.')
# Именно в таком порядке: try, группа except, затем else, и только потом finally.
Это не число. Выходим.
Я закрыл файл.