Работа с исключениями в 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: divisionbyzeroDuringhandlingoftheaboveexception, 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, научитесь их вызывать и создавать собственные.
Статья хорошая но переведена и оформлена УЖАСНО!!!
Форматирование в Питоне принципиально важно!!!
А у вас даже пробелы местами пропущены exceptZeroDivisionError: это нормально?
Добрый день. Проверим обязательно. Спасибо за обратную связь.