Работа с исключениями в Python

Обработка исключений Python нужна для того, чтобы каждый раз, когда возникает исключение, приложение не завершалось бы аварийно. Для этой задачи используются блоки try/except, finally и raise. О них и о том, как создать собственные исключения мы и поговорим ниже.

Иерархия исключений в Python

В языке Питон существует огромное количество встроенных типов исключений, но все они представляют определенную иерархию:

BaseException
+– SystemExit
+– KeyboardInterrupt
+– GeneratorExit
+– Exception
+– StopIteration
+– StopAsyncIteration
+– ArithmeticError
| +– FloatingPointError
| +– OverflowError
| +– ZeroDivisionError
+– AssertionError
+– AttributeError
+– BufferError
+– EOFError
+– ImportError
+– ModuleNotFoundError
+– 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
| +– RecursionError
+– SyntaxError
| +– IndentationError
| +– TabError
+– SystemError
+– TypeError
+– ValueError
| +– UnicodeError
| +– UnicodeDecodeError
| +– UnicodeEncodeError
| +– UnicodeTranslateError
+– Warning
+– DeprecationWarning
+– PendingDeprecationWarning
+– RuntimeWarning
+– SyntaxWarning
+– UserWarning
+– FutureWarning
+– ImportWarning
+– UnicodeWarning
+– BytesWarning
+– ResourceWarning

Как вы заметили, все исключения представляют собой подкласс исключения BaseException.

Обработка исключений в Python

Чтобы во всем разобраться нужно детально рассмотреть различные типы исключений, которые появляются при срабатывании исключения в коде Python.

Блоки try/except

Чтобы код не привел к исключению, его стоит заключить в блок ry. Приведем пример:

try:

for i inrange(3):
print(3/i)
except:
print(«Деление на 0»)
print(«Исключение было обработано»)

Приложение вывело сообщение, так как было обработано исключение. Затем идет блок except. Если не будет определен тип исключения, то он перехватит все. Можно сказать, что это общий обработчик исключений.

В том случае, если код в блоке try приводит к исключению, интерпретатор будет искать блок except, указанный ниже. Другая часть кода не будет исполнена в try.

Особенно полезными исключения в Python, если приложение работает с вводом пользователя, так как никогда не знаешь, что он может ввести.

Пример несколько except в Python

Один блок try может иметь несколько блоков except. Приведем примеры с разными вариантами обработки:

a, b =1,0
try:
print(a/b)
print(«Это не будет напечатано»)
print(’10’+10)

exceptTypeError:
print(«Вы сложили значения несовместимых типов»)
exceptZeroDivisionError:
print(«Деление на 0»)

После того, как интерпретатор обнаружит исключение, он проверит блоки except соответствующего блока try, в которых может быть объявлены обрабатываемые типы исключений. Если интерпретатором будет найдено соответствующее исключение, то он исполняет данный блок except.

В примере первая инструкция приводит к ZeroDivisionError. Данная ошибка обрабатывается в блоке ept, однако инструкции в try после первой не исполняются. Все потому, что после первого исключения последующие инструкции пропускаются. Если не удается найти общий или подходящий блоки except, исключение не обрабатывается. Поэтому оставшаяся часть программы не запускается. Однако, если исключение обработать, то код после блоков except и finally будет исполнен.

Пример:

a, b =1,0
try:
print(a/b)
except:
print(«Вы не можете разделить на 0»)
print(«Буде ли это напечатано?»)

Рассмотрим вывод:

Вы не можете разделить на 0
Будет ли это напечатано?

Пример нескольких исключений в одном except

Для обработки нескольких исключений можно применять один блок except. Для этого нужно использовать скобки, иначе интерпретатор вернет синтаксическую ошибку.

try:
print(’10’+10)
print(1/0)
except(TypeError,ZeroDivisionError):
print(«Неверный ввод»)
Неверный ввод

Пример: Общий except после всех блоков except

Завершить все отдельные блоки except можно одним общим. Он применяется для обработки всех исключений, которые не перехватил отдельный except.

try:
print(‘1’+1)
print(sum)
print(1/0)
exceptNameError:
print(«sum не существует»)
exceptZeroDivisionError:
print(«Вы не можете разделить на 0»)
except:
print(«Что-то пошло не так…»)
Что-то пошло не так…

В примере первая инструкция блока пытается осуществить операцию конкатенации строки Python с числом. В результате возникает ошибка TypeError. Когда интерпретатор сталкивается с данной проблемой, он проверяет соответствующий блок except (тот, который ее обрабатывает).

Между блоками try и except нельзя разместить отдельную инструкцию:

try:
print(«1»)
print(«2»)
except:
print(«3»)

В результате возникнет синтаксическая ошибка.

Однако может быть лишь один блок по умолчанию или общий блок типа except. Следующий код вызовет ошибку:«default ‘except:’ mustbelast»:

try:
print(1/0)
except:
raise
except:
print(«Исключениепоймано»)
finally:
print(«Хорошо»)
print(«Пока»)

Блок finally в Python

Блок finally можно добавить после последнего блока exept. Он исполнит инструкцию при любых условиях:

try:
print(1/0)
exceptValueError:
print(«Это ошибка значения»)
finally:
print(«Это будет напечатано в любом случае.»)
Это будет напечатано в любом случае.

Traceback (mostrecentcalllast):
File “<pyshell#113>”, line 2, in<module>
print(1/0)
ZeroDivisionError: divisionbyzero

Пример того, если исключение будет перехватываться в except:

try:
print(1/0)
exceptZeroDivisionError:
print(2/0)
finally:
print(«Ничего не происходит»)
Ничего не происходит

Traceback (mostrecentcalllast):
File «<pyshell#1>», line 2, in<module>
print(1/0)
ZeroDivisionError: divisionbyzero

Duringhandlingoftheaboveexception, anotherexceptionoccurred:

Traceback (mostrecentcalllast):
File «<pyshell#1>», line 4, in<module>
print(2/0)
ZeroDivisionError: divisionbyzero

Как видите, код в блоке finally исполняется в любом случае.

Ключевое слово raise в Python

В некоторых случаях приходится разбираться с проблемами посредством вызова исключений. Здесь не сработает обычная инструкция print:

raiseZeroDivisionError
Traceback (mostrecentcalllast):
File «<pyshell#2>», line 1, in<module>
raiseZeroDivisionError
ZeroDivisionError

Пример операции деления:

a,b=int(input()),int(input())# вводим 1 затем 0
if b==0:
raiseZeroDivisionError
Traceback (mostrecentcalllast):
File «<pyshell#2>», line 3, in<module>
raiseZeroDivisionError
ZeroDivisionError

Ввод пользователя в переменные и b конвертируется в целые числа. После чего проверяется, соответствует ли и нулю. Если да, то будет вызван ZeroDivisionError.

Пример того, если добавить тоже самое в блоки try-except (если ввести 1 и 0).

a,b=int(input()),int(input())
try:
if b==0:
raiseZeroDivisionError
except:
print(«Деление на 0»)
print(«Будет ли это напечатано?»)
1
0
Деление на 0
Будет ли это напечатано?

Приведем еще несколько примеров:

raiseKeyError
Traceback (mostrecentcalllast):
File “<pyshell#180>”, line 1, in<module>
raiseKeyError
KeyError

Пример: Raise без определенного исключения в Python

Программист может использовать raise без указания того, какое исключение вызвать. В таком случае будет вызвано исключение, которое произошло. По этой причине его можно применять только в блоке except.

try:
print(‘1’+1)
except:
raise
Traceback (mostrecentcalllast):
File “<pyshell#152>”, line 2, in<module>
print(‘1’+1)
TypeError: mustbestr, notint

Пример Raise с аргументом в Python

Еще можно указать аргумент к определенному исключению в raise. Это делается с помощью доп. деталей исключения:

raiseValueError(«Несоответствующее значение»)
Traceback (mostrecentcalllast):
File «<pyshell#3>», line 1, in<module>
raiseValueError(«Несоответствующее значение»)
ValueError: Несоответствующее значение

Утверждение assert в Python

Утверждение (assert) – это санитарная проверка для вашего параноидального, циничного «Я». Если возвращается значение FalseОно принимает инструкцию как аргумент и вызывает исключения Python. Иначе выполняет операцию NOP (No-operation).

assert(True)
# код работает дальше

Пример того, если бы инструкция была False:

assert(1==0)
Traceback (mostrecentcalllast):
File “<pyshell#157>”, line 1, in<module>
assert(1==0)
AssertionError

Приведем другой пример:

try:
print(1)
assert2+2==4
print(2)
assert1+2==4
print(3)
except:
print(«assertFalse.»)
raise
finally:
print(«Хорошо»)
print(«Пока»)

Вывод следующий:

1
2
assertFalse.
Хорошо
Traceback (mostrecentcalllast):
File “<pyshell#157>”, line 5, in<module>
assert 1+2==4
AssertionError

Утверждения assertможно использовать для проверки валидности ввода/вывода в функции.

Пример: Второй аргумент для assert

Чтобы дать доп. информацию о проблеме, предоставьте второй аргумент:

assertFalse,»Это проблема»
Traceback (mostrecentcalllast):
File “<pyshell#173>”, line 1, in<module>
assertFalse,”Это проблема”
AssertionError: Это проблема

Объявление собственных исключений Python

Теперь рассмотрим процесс создание собственных исключений, создав для этого новый класс из класса Exception. Впоследствии его можно вызывать в качестве любого другого типа исключения.

classMyError(Exception):
print(«Это проблема»)

raiseMyError(«ошибкаMyError»)
Traceback (mostrecentcalllast):
File “<pyshell#179>”, line 1, in<module>
raiseMyError(“ошибкаMyError”)
MyError: ошибкаMyError

Заключение

Приведенная нами информация поможет вам задать дополнительную безопасность коду. Воспользуйтесь возможностью обработки исключений Python, научитесь их вызывать и создавать собственные.

2 комментария для “Работа с исключениями в Python

  • 28.03.2021 в 14:27
    Постоянная ссылка

    Статья хорошая но переведена и оформлена УЖАСНО!!!

    Форматирование в Питоне принципиально важно!!!

    А у вас даже пробелы местами пропущены exceptZeroDivisionError: это нормально?

  • 08.04.2021 в 03:22
    Постоянная ссылка

    Добрый день. Проверим обязательно. Спасибо за обратную связь.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *