Python. Обработка ошибок
Исключительная ситуация (exception) - это особый вид объектов Python, которые сообщают о возникновении ошибок в коде.
Обработка исключений
При возникновении ошибки, объект исключительной ситуации начинает передаваться вверх по списку вызова функций,
приведших к участку кода с ошибкой. Для того, чтобы узнать и как-то отреагировать на возникшую ошибку,
в языке Python есть специальный составной оператор try-except
, который позволяет перехватить исключение.
Объявление перехватчика исключений выглядит следующим образом:
try:
<Код, который может вызвать ошибку>
except:
<Код выполнится, если возникло исключение>
else:
<Код выполнится в случае, если исключения не было>
finally:
<Код выполнится в любом случае>
Секции else
и finally
являются необязательными. При записи оператора их можно не указывать.
Рассмотрим пример с функцией, которая выполняет деление двух чисел.
def delenie(a, b):
return a / b
print(delenie(1, 0)) # Будет ошибка ZeroDivisionError: division by zero
Теперь решим, что ошибка нам не нужна. Просто будем возвращать 0. Заключим строки кода, которые могут вызвать ошибку в try-except
def delenie(a, b):
try:
result = a / b
except:
result = 0
return result
print(delenie(1, 0)) # Напечатает 0
У такой реализации функции delenie()
есть одна особенность. Значение 0 будет возвращено для любой ошибки, которая может
возникнуть в процессе деления. Например, попробуем разделить число на строку
Теперь, сделаем так, чтобы значение 0 возвращалось только для ошибок деления на 0, а остальные ошибки оставались необработанными.
Для этого объявление секции except
может быть расширено следующим образом
try:
<Код, который может вызвать ошибку>
except <ТипИсключения> as e:
<Код выполнится, если возникло исключение ТипИсключения>
В нашем случае, в качестве <ТипИсключения>
нужно указать ZeroDivisionError
.
def delenie(a, b):
try:
result = a / b
except ZeroDivisionError as e:
result = 0
return result
print(delenie(1, 0)) # Напечатает 0
print(delenie(1, 'строка')) # Ошибка TypeError: unsupported operand type(s) for /: 'int' and 'str'
Исключения в Python выстроены в отношения тип-подтип. При указании типа исключения в except
, в
этом блоке будет обработано исключение не только указанного типа, но и всех его подтипов.
Например, согласно документации,
ZeroDivisionError
является подтипом более общего типа ArithmeticError
, который в свою очередь содержит
ещё такие подтипы как OverflowError
и FloatingPointError
. При указании except ArithmeticError as e:
,
в указанный блок попадут исключения всех трех его подтипов.
Самым базовым типом исключения является Exception
. Если указать его в except
, то в эту секцию
попадут вообще все возникшие исключения. Таким образом, следующие два обработчика исключений
эквивалентны:
try:
...
except Exception as e:
...
# эквивалентно записи без указания типа исключения
try:
...
except:
...
Можно указывать несколько секций except
. Если мы хотим обрабатывать ZeroDivisionError
и OverflowError
отдельно,
то можем записать обработчик так
Например, если в нашей функции delenie()
мы захотим, чтобы при делении на 0 возвращалось 0, а при несовместимости типов (делении на строку),
возвращалось None
, то можем записать так
def delenie(a, b):
try:
result = a / b
except ZeroDivisionError as e:
result = 0
except TypeError as e:
result = None
return result
print(delenie(1, 0)) # Напечатает 0
print(delenie(1, 'строка')) # Напечатает None
Выбрасывание исключений
Можно не только обрабатывать исключительные ситуации, но и генерировать свои. Для этого служит оператор raise
.
Синтаксис записи оператора:
В качестве <ТипИсключения>
можно использовать любой из существующих в Python типов. Если не знаете, какой лучше, то просто используйте Exception
.
В <Параметры>
обычно указывается просто строка с описанием ошибки.
При вызове оператора raise
выполнение текущей функции останавливается, и исключение передается в вызвавшую её функцию. Если там
нет блока try-except
, то выполнение вызвавшей функции так же останавливается и исключение передается ещё выше по стеку вызова и так далее.
Если try-except
нигде в коде программы так и не встретится, то вы увидите сообщение об ошибке в консоли. Такие исключения
ещё называются необработанными.