Содержание:развернуть
- Как устроен механизм исключений
- Как обрабатывать исключения в Python (try except)
-
As — сохраняет ошибку в переменную
-
Finally — выполняется всегда
-
Else — выполняется когда исключение не было вызвано
-
Несколько блоков except
-
Несколько типов исключений в одном блоке except
-
Raise — самостоятельный вызов исключений
-
Как пропустить ошибку
- Исключения в lambda функциях
- 20 типов встроенных исключений в Python
- Как создать свой тип Exception
Программа, написанная на языке Python, останавливается сразу как обнаружит ошибку. Ошибки могут быть (как минимум) двух типов:
- Синтаксические ошибки — возникают, когда написанное выражение не соответствует правилам языка (например, написана лишняя скобка);
- Исключения — возникают во время выполнения программы (например, при делении на ноль).
Синтаксические ошибки исправить просто (если вы используете IDE, он их подсветит). А вот с исключениями всё немного сложнее — не всегда при написании программы можно сказать возникнет или нет в данном месте исключение. Чтобы приложение продолжило работу при возникновении проблем, такие ошибки нужно перехватывать и обрабатывать с помощью блока try/except.
Как устроен механизм исключений
В Python есть встроенные исключения, которые появляются после того как приложение находит ошибку. В этом случае текущий процесс временно приостанавливается и передает ошибку на уровень вверх до тех пор, пока она не будет обработано. Если ошибка не будет обработана, программа прекратит свою работу (а в консоли мы увидим Traceback с подробным описанием ошибки).
💁♂️ Пример: напишем скрипт, в котором функция ожидает число, а мы передаём сроку (это вызовет исключение «TypeError»):
def b(value):
print("-> b")
print(value + 1) # ошибка тут
def a(value):
print("-> a")
b(value)
a("10")
> -> a
> -> b
> Traceback (most recent call last):
> File "test.py", line 11, in <module>
> a("10")
> File "test.py", line 8, in a
> b(value)
> File "test.py", line 3, in b
> print(value + 1)
> TypeError: can only concatenate str (not "int") to str
В данном примере мы запускаем файл «test.py» (через консоль). Вызывается функция «a«, внутри которой вызывается функция «b«. Все работает хорошо до сточки print(value + 1). Тут интерпретатор понимает, что нельзя конкатенировать строку с числом, останавливает выполнение программы и вызывает исключение «TypeError».
Далее ошибка передается по цепочке в обратном направлении: «b» → «a» → «test.py«. Так как в данном примере мы не позаботились обработать эту ошибку, вся информация по ошибке отобразится в консоли в виде Traceback.
Traceback (трассировка) — это отчёт, содержащий вызовы функций, выполненные в определенный момент. Трассировка помогает узнать, что пошло не так и в каком месте это произошло.
Traceback лучше читать снизу вверх ↑
В нашем примере Traceback содержится следующую информацию (читаем снизу вверх):
TypeError— тип ошибки (означает, что операция не может быть выполнена с переменной этого типа);can only concatenate str (not "int") to str— подробное описание ошибки (конкатенировать можно только строку со строкой);- Стек вызова функций (1-я линия — место, 2-я линия — код). В нашем примере видно, что в файле «test.py» на 11-й линии был вызов функции «a» со строковым аргументом «10». Далее был вызов функции «b».
print(value + 1)это последнее, что было выполнено — тут и произошла ошибка. most recent call last— означает, что самый последний вызов будет отображаться последним в стеке (в нашем примере последним выполнилсяprint(value + 1)).
В Python ошибку можно перехватить, обработать, и продолжить выполнение программы — для этого используется конструкция try ... except ....
Как обрабатывать исключения в Python (try except)
В Python исключения обрабатываются с помощью блоков try/except. Для этого операция, которая может вызвать исключение, помещается внутрь блока try. А код, который должен быть выполнен при возникновении ошибки, находится внутри except.
Например, вот как можно обработать ошибку деления на ноль:
try:
a = 7 / 0
except:
print('Ошибка! Деление на 0')
Здесь в блоке try находится код a = 7 / 0 — при попытке его выполнить возникнет исключение и выполнится код в блоке except (то есть будет выведено сообщение «Ошибка! Деление на 0»). После этого программа продолжит свое выполнение.
💭 PEP 8 рекомендует, по возможности, указывать конкретный тип исключения после ключевого слова except (чтобы перехватывать и обрабатывать конкретные исключения):
try:
a = 7 / 0
except ZeroDivisionError:
print('Ошибка! Деление на 0')
Однако если вы хотите перехватывать все исключения, которые сигнализируют об ошибках программы, используйте тип исключения Exception:
try:
a = 7 / 0
except Exception:
print('Любая ошибка!')
As — сохраняет ошибку в переменную
Перехваченная ошибка представляет собой объект класса, унаследованного от «BaseException». С помощью ключевого слова as можно записать этот объект в переменную, чтобы обратиться к нему внутри блока except:
try:
file = open('ok123.txt', 'r')
except FileNotFoundError as e:
print(e)
> [Errno 2] No such file or directory: 'ok123.txt'
В примере выше мы обращаемся к объекту класса «FileNotFoundError» (при выводе на экран через print отобразится строка с полным описанием ошибки).
У каждого объекта есть поля, к которым можно обращаться (например если нужно логировать ошибку в собственном формате):
import datetime
now = datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S")
try:
file = open('ok123.txt', 'r')
except FileNotFoundError as e:
print(f"{now} [FileNotFoundError]: {e.strerror}, filename: {e.filename}")
> 20-11-2021 18:42:01 [FileNotFoundError]: No such file or directory, filename: ok123.txt
Finally — выполняется всегда
При обработке исключений можно после блока try использовать блок finally. Он похож на блок except, но команды, написанные внутри него, выполняются обязательно. Если в блоке try не возникнет исключения, то блок finally выполнится так же, как и при наличии ошибки, и программа возобновит свою работу.
Обычно try/except используется для перехвата исключений и восстановления нормальной работы приложения, а try/finally для того, чтобы гарантировать выполнение определенных действий (например, для закрытия внешних ресурсов, таких как ранее открытые файлы).
В следующем примере откроем файл и обратимся к несуществующей строке:
file = open('ok.txt', 'r')
try:
lines = file.readlines()
print(lines[5])
finally:
file.close()
if file.closed:
print("файл закрыт!")
> файл закрыт!
> Traceback (most recent call last):
> File "test.py", line 5, in <module>
> print(lines[5])
> IndexError: list index out of range
Даже после исключения «IndexError», сработал код в секции finally, который закрыл файл.
p.s. данный пример создан для демонстрации, в реальном проекте для работы с файлами лучше использовать менеджер контекста with.
Также можно использовать одновременно три блока try/except/finally. В этом случае:
- в
try— код, который может вызвать исключения; - в
except— код, который должен выполниться при возникновении исключения; - в
finally— код, который должен выполниться в любом случае.
def sum(a, b):
res = 0
try:
res = a + b
except TypeError:
res = int(a) + int(b)
finally:
print(f"a = {a}, b = {b}, res = {res}")
sum(1, "2")
> a = 1, b = 2, res = 3
Else — выполняется когда исключение не было вызвано
Иногда нужно выполнить определенные действия, когда код внутри блока try не вызвал исключения. Для этого используется блок else.
Допустим нужно вывести результат деления двух чисел и обработать исключения в случае попытки деления на ноль:
b = int(input('b = '))
c = int(input('c = '))
try:
a = b / c
except ZeroDivisionError:
print('Ошибка! Деление на 0')
else:
print(f"a = {a}")
> b = 10
> c = 1
> a = 10.0
В этом случае, если пользователь присвоит переменной «с» ноль, то появится исключение и будет выведено сообщение «‘Ошибка! Деление на 0′», а код внутри блока else выполняться не будет. Если ошибки не будет, то на экране появятся результаты деления.
Несколько блоков except
В программе может возникнуть несколько исключений, например:
- Ошибка преобразования введенных значений к типу
float(«ValueError»); - Деление на ноль («ZeroDivisionError»).
В Python, чтобы по-разному обрабатывать разные типы ошибок, создают несколько блоков except:
try:
b = float(input('b = '))
c = float(input('c = '))
a = b / c
except ZeroDivisionError:
print('Ошибка! Деление на 0')
except ValueError:
print('Число введено неверно')
else:
print(f"a = {a}")
> b = 10
> c = 0
> Ошибка! Деление на 0
> b = 10
> c = питон
> Число введено неверно
Теперь для разных типов ошибок есть свой обработчик.
Несколько типов исключений в одном блоке except
Можно также обрабатывать в одном блоке except сразу несколько исключений. Для этого они записываются в круглых скобках, через запятую сразу после ключевого слова except. Чтобы обработать сообщения «ZeroDivisionError» и «ValueError» в одном блоке записываем их следующим образом:
try:
b = float(input('b = '))
c = float(input('c = '))
a = b / c
except (ZeroDivisionError, ValueError) as er:
print(er)
else:
print('a = ', a)
При этом переменной er присваивается объект того исключения, которое было вызвано. В результате на экран выводятся сведения о конкретной ошибке.
Raise — самостоятельный вызов исключений
Исключения можно генерировать самостоятельно — для этого нужно запустить оператор raise.
min = 100
if min > 10:
raise Exception('min must be less than 10')
> Traceback (most recent call last):
> File "test.py", line 3, in <module>
> raise Exception('min value must be less than 10')
> Exception: min must be less than 10
Перехватываются такие сообщения точно так же, как и остальные:
min = 100
try:
if min > 10:
raise Exception('min must be less than 10')
except Exception:
print('Моя ошибка')
> Моя ошибка
Кроме того, ошибку можно обработать в блоке except и пробросить дальше (вверх по стеку) с помощью raise:
min = 100
try:
if min > 10:
raise Exception('min must be less than 10')
except Exception:
print('Моя ошибка')
raise
> Моя ошибка
> Traceback (most recent call last):
> File "test.py", line 5, in <module>
> raise Exception('min must be less than 10')
> Exception: min must be less than 10
Как пропустить ошибку
Иногда ошибку обрабатывать не нужно. В этом случае ее можно пропустить с помощью pass:
try:
a = 7 / 0
except ZeroDivisionError:
pass
Исключения в lambda функциях
Обрабатывать исключения внутри lambda функций нельзя (так как lambda записывается в виде одного выражения). В этом случае нужно использовать именованную функцию.
20 типов встроенных исключений в Python
Иерархия классов для встроенных исключений в Python выглядит так:
BaseException
SystemExit
KeyboardInterrupt
GeneratorExit
Exception
ArithmeticError
AssertionError
...
...
...
ValueError
Warning
Все исключения в Python наследуются от базового BaseException:
SystemExit— системное исключение, вызываемое функциейsys.exit()во время выхода из приложения;KeyboardInterrupt— возникает при завершении программы пользователем (чаще всего при нажатии клавиш Ctrl+C);GeneratorExit— вызывается методомcloseобъектаgenerator;Exception— исключения, которые можно и нужно обрабатывать (предыдущие были системными и их трогать не рекомендуется).
От Exception наследуются:
1 StopIteration — вызывается функцией next в том случае если в итераторе закончились элементы;
2 ArithmeticError — ошибки, возникающие при вычислении, бывают следующие типы:
FloatingPointError— ошибки при выполнении вычислений с плавающей точкой (встречаются редко);OverflowError— результат вычислений большой для текущего представления (не появляется при операциях с целыми числами, но может появиться в некоторых других случаях);ZeroDivisionError— возникает при попытке деления на ноль.
3 AssertionError — выражение, используемое в функции assert неверно;
4 AttributeError — у объекта отсутствует нужный атрибут;
5 BufferError — операция, для выполнения которой требуется буфер, не выполнена;
6 EOFError — ошибка чтения из файла;
7 ImportError — ошибка импортирования модуля;
8 LookupError — неверный индекс, делится на два типа:
IndexError— индекс выходит за пределы диапазона элементов;KeyError— индекс отсутствует (для словарей, множеств и подобных объектов);
9 MemoryError — память переполнена;
10 NameError — отсутствует переменная с данным именем;
11 OSError — исключения, генерируемые операционной системой:
ChildProcessError— ошибки, связанные с выполнением дочернего процесса;ConnectionError— исключения связанные с подключениями (BrokenPipeError, ConnectionResetError, ConnectionRefusedError, ConnectionAbortedError);FileExistsError— возникает при попытке создания уже существующего файла или директории;FileNotFoundError— генерируется при попытке обращения к несуществующему файлу;InterruptedError— возникает в том случае если системный вызов был прерван внешним сигналом;IsADirectoryError— программа обращается к файлу, а это директория;NotADirectoryError— приложение обращается к директории, а это файл;PermissionError— прав доступа недостаточно для выполнения операции;ProcessLookupError— процесс, к которому обращается приложение не запущен или отсутствует;TimeoutError— время ожидания истекло;
12 ReferenceError — попытка доступа к объекту с помощью слабой ссылки, когда объект не существует;
13 RuntimeError — генерируется в случае, когда исключение не может быть классифицировано или не подпадает под любую другую категорию;
14 NotImplementedError — абстрактные методы класса нуждаются в переопределении;
15 SyntaxError — ошибка синтаксиса;
16 SystemError — сигнализирует о внутренне ошибке;
17 TypeError — операция не может быть выполнена с переменной этого типа;
18 ValueError — возникает когда в функцию передается объект правильного типа, но имеющий некорректное значение;
19 UnicodeError — исключение связанное с кодирование текста в unicode, бывает трех видов:
UnicodeEncodeError— ошибка кодирования;UnicodeDecodeError— ошибка декодирования;UnicodeTranslateError— ошибка переводаunicode.
20 Warning — предупреждение, некритическая ошибка.
💭 Посмотреть всю цепочку наследования конкретного типа исключения можно с помощью модуля inspect:
import inspect
print(inspect.getmro(TimeoutError))
> (<class 'TimeoutError'>, <class 'OSError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>)
📄 Подробное описание всех классов встроенных исключений в Python смотрите в официальной документации.
Как создать свой тип Exception
В Python можно создавать свои исключения. При этом есть одно обязательное условие: они должны быть потомками класса Exception:
class MyError(Exception):
def __init__(self, text):
self.txt = text
try:
raise MyError('Моя ошибка')
except MyError as er:
print(er)
> Моя ошибка
С помощью try/except контролируются и обрабатываются ошибки в приложении. Это особенно актуально для критически важных частей программы, где любые «падения» недопустимы (или могут привести к негативным последствиям). Например, если программа работает как «демон», падение приведет к полной остановке её работы. Или, например, при временном сбое соединения с базой данных, программа также прервёт своё выполнение (хотя можно было отловить ошибку и попробовать соединиться в БД заново).
Вместе с try/except можно использовать дополнительные блоки. Если использовать все блоки описанные в статье, то код будет выглядеть так:
try:
# попробуем что-то сделать
except (ZeroDivisionError, ValueError) as e:
# обрабатываем исключения типа ZeroDivisionError или ValueError
except Exception as e:
# исключение не ZeroDivisionError и не ValueError
# поэтому обрабатываем исключение общего типа (унаследованное от Exception)
# сюда не сходят исключения типа GeneratorExit, KeyboardInterrupt, SystemExit
else:
# этот блок выполняется, если нет исключений
# если в этом блоке сделать return, он не будет вызван, пока не выполнился блок finally
finally:
# этот блок выполняется всегда, даже если нет исключений else будет проигнорирован
# если в этом блоке сделать return, то return в блоке
Подробнее о работе с исключениями в Python можно ознакомиться в официальной документации.
В этом руководстве мы расскажем, как обрабатывать исключения в Python с помощью try и except. Рассмотрим общий синтаксис и простые примеры, обсудим, что может пойти не так, и предложим меры по исправлению положения.
Зачастую разработчик может предугадать возникновение ошибок при работе даже синтаксически и логически правильной программы. Эти ошибки могут быть вызваны неверными входными данными или некоторыми предсказуемыми несоответствиями.
Для обработки большей части этих ошибок как исключений в Python есть блоки try и except.
Для начала разберем синтаксис операторов try и except в Python. Общий шаблон представлен ниже:
try:
# В этом блоке могут быть ошибки
except <error type>:
# Сделай это для обработки исключения;
# выполняется, если блок try выбрасывает ошибку
else:
# Сделай это, если блок try выполняется успешно, без ошибок
finally:
# Этот блок выполняется всегда
Давайте посмотрим, для чего используются разные блоки.
Блок try
Блок try — это блок кода, который вы хотите попробовать выполнить. Однако во время выполнения из-за какого-нибудь исключения могут возникнуть ошибки. Поэтому этот блок может не работать должным образом.
Блок except
Блок except запускается, когда блок try не срабатывает из-за исключения. Инструкции в этом блоке часто дают некоторый контекст того, что пошло не так внутри блока try.
Если собираетесь перехватить ошибку как исключение, в блоке except нужно обязательно указать тип этой ошибки. В приведенном выше сниппете место для указания типа ошибки обозначено плейсхолдером <error type> .
except можно использовать и без указания типа ошибки. Но лучше так не делать. При таком подходе не учитывается, что возникающие ошибки могут быть разных типов. То есть вы будете знать, что что-то пошло не так, но что именно произошло, какая была ошибка — вам будет не известно.
При попытке выполнить код внутри блока try также существует вероятность возникновения нескольких ошибок.
Например, вы можете попытаться обратиться к элементу списка по индексу, выходящему за пределы допустимого диапазона, использовать неправильный ключ словаря и попробовать открыть несуществующий файл – и все это внутри одного блока try.
В результате вы можете столкнуться с IndexError, KeyError и FileNotFoundError. В таком случае нужно добавить столько блоков except, сколько ошибок ожидается – по одному для каждого типа ошибки.
Блок else
Блок else запускается только в том случае, если блок try выполняется без ошибок. Это может быть полезно, когда нужно выполнить ещё какие-то действия после успешного выполнения блока try. Например, после успешного открытия файла вы можете прочитать его содержимое.
Блок finally
Блок finally выполняется всегда, независимо от того, что происходит в других блоках. Это полезно, когда вы хотите освободить ресурсы после выполнения определенного блока кода.
Примечание: блоки else и finally не являются обязательными. В большинстве случаев вы можете использовать только блок try, чтобы что-то сделать, и перехватывать ошибки как исключения внутри блока except.
[python_ad_block]
Итак, теперь давайте используем полученные знания для обработки исключений в Python. Приступим!
Обработка ZeroDivisionError
Рассмотрим функцию divide(), показанную ниже. Она принимает два аргумента – num и div – и возвращает частное от операции деления num/div.
def divide(num,div):
return num/div
Вызов функции с разными аргументами возвращает ожидаемый результат:
res = divide(100,8) print(res) # Output # 12.5 res = divide(568,64) print(res) # Output # 8.875
Этот код работает нормально, пока вы не попробуете разделить число на ноль:
divide(27,0)
Вы видите, что программа выдает ошибку ZeroDivisionError:
# Output
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
<ipython-input-19-932ea024ce43> in <module>()
----> 1 divide(27,0)
<ipython-input-1-c98670fd7a12> in divide(num, div)
1 def divide(num,div):
----> 2 return num/div
ZeroDivisionError: division by zero
Можно обработать деление на ноль как исключение, выполнив следующие действия:
- В блоке
tryпоместите вызов функцииdivide(). По сути, вы пытаетесь разделитьnumнаdiv(try в переводе с английского — «пытаться», — прим. перев.). - В блоке
exceptобработайте случай, когдаdivравен 0, как исключение. - В результате этих действий при делении на ноль больше не будет выбрасываться ZeroDivisionError. Вместо этого будет выводиться сообщение, информирующее пользователя, что он попытался делить на ноль.
Вот как все это выглядит в коде:
try:
res = divide(num,div)
print(res)
except ZeroDivisionError:
print("You tried to divide by zero :( ")
При корректных входных данных наш код по-прежнему работает великолепно:
divide(10,2) # Output # 5.0
Когда же пользователь попытается разделить на ноль, он получит уведомление о возникшем исключении. Таким образом, программа завершается корректно и без ошибок.
divide(10,0) # Output # You tried to divide by zero :(
Обработка TypeError
В этом разделе мы разберем, как использовать try и except для обработки TypeError в Python.
Рассмотрим функцию add_10(). Она принимает число в качестве аргумента, прибавляет к нему 10 и возвращает результат этого сложения.
def add_10(num):
return num + 10
Вы можете вызвать функцию add_10() с любым числом, и она будет работать нормально, как показано ниже:
result = add_10(89) print(result) # Output # 99
Теперь попробуйте вызвать функцию add_10(), передав ей в качестве аргумента не число, а строку.
add_10 ("five")
Ваша программа вылетит со следующим сообщением об ошибке:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-15-9844e949c84e> in <module>()
----> 1 add_10("five")
<ipython-input-13-2e506d74d919> in add_10(num)
1 def add_10(num):
----> 2 return num + 10
TypeError: can only concatenate str (not "int") to str
Сообщение об ошибке TypeError: can only concatenate str (not "int") to str говорит о том, что можно сложить только две строки, а не добавить целое число к строке.
Обработаем TypeError:
- В блок try мы помещаем вызов функции
add_10()с my_num в качестве аргумента. Если аргумент допустимого типа, исключений не возникнет. - В противном случае срабатывает блок
except, в который мы помещаем вывод уведомления для пользователя о том, что аргумент имеет недопустимый тип.
Это показано ниже:
my_num = "five"
try:
result = add_10(my_num)
print(result)
except TypeError:
print("The argument `num` should be a number")
Поскольку теперь вы обработали TypeError как исключение, при передаче невалидного аргумента ошибка не возникает. Вместо нее выводится сообщение, что аргумент имеет недопустимый тип.
The argument `num` should be a number
Обработка IndexError
Если вам приходилось работать со списками или любыми другими итерируемыми объектами, вы, вероятно, сталкивались с IndexError.
Это связано с тем, что часто бывает сложно отслеживать все изменения в итерациях. И вы можете попытаться получить доступ к элементу по невалидному индексу.
В этом примере список my_list состоит из 4 элементов. Допустимые индексы — 0, 1, 2 и 3 и -1, -2, -3, -4, если вы используете отрицательную индексацию.
Поскольку 2 является допустимым индексом, вы видите, что элемент с этим индексом (C++) распечатывается:
my_list = ["Python","C","C++","JavaScript"] print(my_list[2]) # Output # C++
Но если вы попытаетесь получить доступ к элементу по индексу, выходящему за пределы допустимого диапазона, вы столкнетесь с IndexError:
print(my_list[4])
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-7-437bc6501dea> in <module>()
1 my_list = ["Python","C","C++","JavaScript"]
----> 2 print(my_list[4])
IndexError: list index out of range
Теперь вы уже знакомы с шаблоном, и вам не составит труда использовать try и except для обработки данной ошибки.
В приведенном ниже фрагменте кода мы пытаемся получить доступ к элементу по индексу search_idx.
search_idx = 3
try:
print(my_list[search_idx])
except IndexError:
print("Sorry, the list index is out of range")
Здесь search_idx = 3 является допустимым индексом, поэтому в результате выводится соответствующий элемент — JavaScript.
Если search_idx находится за пределами допустимого диапазона индексов, блок except перехватывает IndexError как исключение, и больше нет длинных сообщений об ошибках.
search_idx = 4
try:
print(my_list[search_idx])
except IndexError:
print("Sorry, the list index is out of range")
Вместо этого отображается сообщение о том, что search_idx находится вне допустимого диапазона индексов:
Sorry, the list index is out of range
Обработка KeyError
Вероятно, вы уже сталкивались с KeyError при работе со словарями в Python.
Рассмотрим следующий пример, где у нас есть словарь my_dict.
my_dict ={"key1":"value1","key2":"value2","key3":"value3"}
search_key = "non-existent key"
print(my_dict[search_key])
В словаре my_dict есть 3 пары «ключ-значение»: key1:value1, key2:value2 и key3:value3.
Теперь попытаемся получить доступ к значению, соответствующему несуществующему ключу non-existent key.
Как и ожидалось, мы получим KeyError:
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-2-2a61d404be04> in <module>()
1 my_dict ={"key1":"value1","key2":"value2","key3":"value3"}
2 search_key = "non-existent key"
----> 3 my_dict[search_key]
KeyError: 'non-existent key'
Вы можете обработать KeyError почти так же, как и IndexError.
- Пробуем получить доступ к значению, которое соответствует ключу, определенному
search_key. - Если
search_key— валидный ключ, мы распечатываем соответствующее значение. - Если ключ невалиден и возникает исключение — задействуется блок except, чтобы сообщить об этом пользователю.
Все это можно видеть в следующем коде:
try:
print(my_dict[search_key])
except KeyError:
print("Sorry, that's not a valid key!")
# Output:
# Sorry, that's not a valid key!
Если вы хотите предоставить дополнительный контекст, например имя невалидного ключа, это тоже можно сделать. Возможно, ключ оказался невалидным из-за ошибки в написании. Если вы укажете этот ключ в сообщении, это поможет пользователю исправить опечатку.
Вы можете сделать это, перехватив невалидный ключ как <error_msg> и используя его в сообщении, которое печатается при возникновении исключения:
try:
print(my_dict[search_key])
except KeyError as error_msg:
print(f"Sorry,{error_msg} is not a valid key!")
Обратите внимание, что теперь в сообщении об ошибки указано также и имя несуществующего ключа:
Sorry, 'non-existent key' is not a valid key!
Обработка FileNotFoundError
При работе с файлами в Python часто возникает ошибка FileNotFoundError.
В следующем примере мы попытаемся открыть файл my_file.txt, указав его путь в функции open(). Мы хотим прочитать файл и вывести его содержимое.
Однако мы еще не создали этот файл в указанном месте.
my_file = open("/content/sample_data/my_file.txt")
contents = my_file.read()
print(contents)
Поэтому, попытавшись запустить приведенный выше фрагмент кода, мы получим FileNotFoundError:
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
<ipython-input-4-4873cac1b11a> in <module>()
----> 1 my_file = open("my_file.txt")
FileNotFoundError: [Errno 2] No such file or directory: 'my_file.txt'
А с помощью try и except мы можем сделать следующее:
- Попробуем открыть файл в блоке
try. - Обработаем
FileNotFoundErrorв блокеexcept, сообщив пользователю, что он попытался открыть несуществующий файл. - Если блок
tryзавершается успешно и файл действительно существует, прочтем и распечатаем содержимое. - В блоке
finallyзакроем файл, чтобы не терять ресурсы. Файл будет закрыт независимо от того, что происходило на этапах открытия и чтения.
try:
my_file = open("/content/sample_data/my_file.txt")
except FileNotFoundError:
print(f"Sorry, the file does not exist")
else:
contents = my_file.read()
print(contents)
finally:
my_file.close()
Обратите внимание: мы обработали ошибку как исключение, и программа завершает работу, отображая следующее сообщение:
Sorry, the file does not exist
Теперь рассмотрим случай, когда срабатывает блок else. Файл my_file.txt теперь присутствует по указанному ранее пути.

Вот содержимое этого файла:

Теперь повторный запуск нашего кода работает должным образом.
На этот раз файл my_file.txt присутствует, поэтому запускается блок else и содержимое распечатывается, как показано ниже:

Надеемся, теперь вы поняли, как обрабатывать исключения при работе с файлами.
Заключение
В этом руководстве мы рассмотрели, как обрабатывать исключения в Python с помощью try и except.
Также мы разобрали на примерах, какие типы исключений могут возникать и как при помощи except ловить наиболее распространенные ошибки.
Надеемся, вам понравился этот урок. Успехов в написании кода!
Перевод статьи «Python Try and Except Statements – How to Handle Exceptions in Python».
In this Python Tutorial let us learn about the 3 different pieces of information that you can extract and use from the Exceptions caught on your except clauses, and see the best ways to use each of these pieces in our Python programs.
Let us start by learning what the 3 pieces of information are.
What kind of information can you get from Exceptions?
You can get the following 3 pieces of data from exceptions
- Exception Type,
- Exception Value a.k.a Error Message, and
- Stack-trace or Traceback Object.
All three of the above information is printed out by the Python Interpreter when our program crashes due to an exception as shown in the following example
>> my_list = [1,2]
>> print (my_list[3])
Traceback (most recent call last):
File "<ipython-input-35-63c7f9106be5>", line 1, in <module>
print (my_list[3])
IndexError: list index out of range
Lines 3,4,5,6 shows the Stack-trace
Line 7 shows the Exception type and Error Message.
Our focus in this article is to learn how to extract the above 3 pieces individually in our except clauses and print them out as needed.
Hence, the rest of the article is all about answering the following questions
- what does each of the information in the above list mean,
- how to extract each of these 3 pieces individually and
- how to use these pieces in our programs.
Piece#1: Printing Exception Type
The Exception Type refers to the class to which the Exception that you have just caught belongs to.
Extracting Piece#1 (Exception Type)
Let us improve our Example 1 above by putting the problematic code into try and except clauses.
try:
my_list = [1,2]
print (my_list[3])
except Exception as e:
print(type(e))
Here, in the try clause, we have declared a List named my_list and initialized the list with 2 items. Then we have tried to print the 3rd/non-existent item in the list.
The except clause catches the IndexError exception and prints out Exception type.
On running the code, we will get the following output
<class 'IndexError'>
As you can see we just extracted and printed out the information about the class to which the exception that we have just caught belongs to!
But how exactly did we do that?
If you have a look at the except clause. In the line
except Exception as e:
what we have done is, we have assigned the caught exception to an object named “e”. Then by using the built-in python function type(), we have printed out the class name that the object e belongs to.
print(type(e))
Where to get more details about Exception Types
Now that we have the “Exception Type”, next we will probably need to get some information about that particular type so that we can get a better understanding of why our code has failed. In order to do that, the best place to start is the official documentation.
For built in exceptions you can have a look at the Python Documentation
For Exception types that come with the libraries that you use with your code, refer to the documentation of your library.
Piece#2: Printing Exception Value a.k.a Error message
The Exception type is definitely useful for debugging, but, a message like IndexError might sound cryptic and a good understandable error-message will make our job of debugging easier without having to look at the documentation.
In other words, if your program is to be run on the command line and you wish to log why the program just crashed then it is better to use an “Error message” rather than an “Exception Type”.
The example below shows how to print such an Error message.
try:
my_list = [1,2]
print (my_list[3])
except Exception as e:
print(e)
This will print the default error message as follows
list index out of range
Each Exception type comes with its own error message. This can be retrieved using the built-in function print().
Say your program is going to be run by a not-so-tech-savvy user, in that case, you might want to print something friendlier. You can do so by passing in the string to be printed along with the constructor as follows.
try:
raise IndexError('Custom message about IndexError')
except Exception as e:
print(e)
This will print
Custom message about IndexError
To understand how the built-in function print() does this magic, and see some more examples of manipulating these error messages, I recommend reading my other article in the link below.
Python Exception Tutorial: Printing Error Messages (5 Examples!)
If you wish to print both the Error message and the Exception type, which I recommend, you can do so like below.
try:
my_list = [1,2]
print (my_list[3])
except Exception as e:
print(repr(e))
This will print something like
IndexError('list index out of range')
Now that we have understood how to get control over the usage of Pieces 1 and 2, let us go ahead and look at the last and most important piece for debugging, the stack-trace which tells us where exactly in our program have the Exception occurred.
Piece#3: Printing/Logging the stack-trace using the traceback object
Stack-trace in Python is packed into an object named traceback object.
This is an interesting one as the traceback class in Python comes with several useful methods to exercise complete control over what is printed.
Let us see how to use these options using some examples!
import traceback
try:
my_list = [1,2]
print (my_list[3])
except Exception:
traceback.print_exc()
This will print something like
Traceback (most recent call last):
File "<ipython-input-38-f9a1ee2cf77a>", line 5, in <module>
print (my_list[3])
IndexError: list index out of range
which contains the entire error messages printed by the Python interpreter if we fail to handle the exception.
Here, instead of crashing the program, we have printed this entire message using our exception handler with the help of the print_exc() method of the traceback class.
The above Example-6 is too simple, as, in the real-world, we will normally have several nested function calls which will result in a deeper stack. Let us see an example of how to control the output in such situations.
def func3():
my_list = [1,2]
print (my_list[3])
def func2():
print('calling func3')
func3()
def func1():
print('calling func2')
func2()
try:
print('calling func1')
func1()
except Exception as e:
traceback.print_exc()
Here in the try clause we call func1(), which in-turn calls func2(), which in-turn calls func3(), which produces an IndexError. Running the code above we get the following output
calling func1
calling func2
calling func3
Traceback (most recent call last):
File "<ipython-input-42-2267707e164f>", line 15, in <module>
func1()
File "<ipython-input-42-2267707e164f>", line 11, in func1
func2()
File "<ipython-input-42-2267707e164f>", line 7, in func2
func3()
File "<ipython-input-42-2267707e164f>", line 3, in func3
print (my_list[3])
IndexError: list index out of range
Say we are not interested in some of the above information. Say we just want to print out the Traceback and skip the error message and Exception type (the last line above), then we can modify the code like shown below.
def func3():
my_list = [1,2]
print (my_list[3])
def func2():
func3()
def func1():
func2()
try:
func1()
except Exception as e:
traceback_lines = traceback.format_exc().splitlines()
for line in traceback_lines:
if line != traceback_lines[-1]:
print(line)
Here we have used the format_exc() method available in the traceback class to get the traceback information as a string and used splitlines() method to transform the string into a list of lines and stored that in a list object named traceback_lines
Then with the help of a simple for loop we have skipped printing the last line with index of -1 to get an output like below
Traceback (most recent call last):
File "<ipython-input-43-aff649563444>", line 3, in <module>
func1()
File "<ipython-input-42-2267707e164f>", line 11, in func1
func2()
File "<ipython-input-42-2267707e164f>", line 7, in func2
func3()
File "<ipython-input-42-2267707e164f>", line 3, in func3
print (my_list[3])
Another interesting variant of formatting the information in the traceback object is to control the depth of stack that is actually printed out.
If your program uses lots of external library code, odds are the stack will get very deep, and printing out each and every level of function call might not be very useful. If you ever find yourself in such a situation you can set the limit argument in the print_exc() method like shown below.
traceback.print_exc(limit=2, file=sys.stdout)
This will limit the number of levels to 2. Let us use this line of code in our Example and see how that behaves
def func3():
my_list = [1,2]
print (my_list[3])
def func2():
func3()
def func1():
func2()
try:
func1()
except Exception as e:
traceback.print_exc(limit=2)
This will print
Traceback (most recent call last):
File "<ipython-input-44-496132ff4faa>", line 12, in <module>
func1()
File "<ipython-input-44-496132ff4faa>", line 9, in func1
func2()
IndexError: list index out of range
As you can see, we have printed only 2 levels of the stack and skipped the 3rd one, just as we wanted!
You can do more things with traceback like formatting the output to suit your needs. If you are interested to learn even more things to do, refer to the official documentation on traceback here
Now that we have seen how to exercise control over what gets printed and how to format them, next let us have a look at some best practices on when to use which piece of information
Best Practices while Printing Exception messages
When to Use Which Piece
- Use Piece#1 only on very short programs and only during the development/testing phase to get some clues on the Exceptions without letting the interpreter crash your program. Once finding out, implement specific handlers to do something about these exceptions. If you are not sure how to handle the exceptions have a look at my other article below where I have explained 3 ways to handle Exceptions
Exceptions in Python: Everything You Need To Know! - Use Piece#2 to print out some friendly information either for yourself or for your user to inform them what exactly is happening.
- Use all 3 pieces on your finished product, so that if an exception ever occurs while your program is running on your client’s computer, you can log the errors and have use that information to fix your bugs.
Where to print
One point worth noting here is that the default file that print() uses is the stdout file stream and not the stderr stream. To use stderr instead, you can modify the code like this
import sys
try:
#some naughty statements that irritate us with exceptions
except Exception as e:
print(e, file=sys.stderr)
The above code is considered better practice, as errors are meant to go to stderr and not stdout.
You can always print these into a separate log file too if that is what you need. This way, you can organize the logs collected in a better manner by separating the informational printouts from the error printouts.
How to print into log files
If you are going to use a log file I suggest using python’s logging module instead of print() statements, as described here
If you are interested in learning how to manually raise exceptions, and what situations you might need to do that you can read this article below
Python: Manually throw/raise an Exception using the “raise” statement
If you are interested in catching and handling multiple exception in a single except clause, you can this article below
Python: 3 Ways to Catch Multiple Exceptions in a single “except” clause
And with that, I will conclude this article!
I hope you enjoyed reading this article and got some value out of it!
Feel free to share it with your friends and colleagues!
Ошибок не допускает только тот, кто ничего не делает и программирование не исключение. С ростом кода и объема разработки, также растет вероятность получить error в терминале. Именно по причине весовой вероятности появления ошибок исключения в python и других языках программирования — это обязательная часть.
Значения исключений и ошибок в Python
Как упоминалась выше, от ошибок в коде никто не застрахован и если новички часто совершают банальные опечатки, то у профессионалов найти ошибку крайне сложно. Когда приходиться часами, а то и днями перебирать все базовые и наследуемые классы очень жалеешь, что прописал обработчик.
В Python обработка исключений имеет колоссальное значение. Неполадки возможны как элементарные, так и скрытые в особенностях языка или логике построения. Если программист считает, что пользователь никогда не сделает ошибки – он их обязательно совершит. Идеального решения в программном коде не существует и существовать не может, следовательно, добавлять исключение и уметь их обрабатывать профессиональная необходимость.

Как устроен механизм исключений
Обычно код выполняться построчно в случае, когда дальнейшее выполнение становится невозможным, программа возвращает exceptions. В отсутствие обработчика исключений ошибка не выявляется и на этом работа программы заканчивается.
На курсах python https://volgograd.videoforme.ru/computer-programming-school/python-for-beginners объясняют, что обработка ошибок происходит во многом за счет пойманного exceptions. Код, который потенциально может быть проломным, оборачивается в своего рода ловушку. Если проблем нет, то все проходит стандартно, но только появляться exceptions мы выходим из потенциально проблемного участка и идем по пути исключения. По сути данный механизм можно условно сравнить if – else, когда все хорошо мы в if, когда сломалось в else (при этом в else также прилетит exceptions).
Синтаксические ошибки (SyntaxError)
От ошибок в синтаксисе никто не застрахован. Конечно, значительно чаще этим грешат новички программирования. Возьмем пример:
.py
employee = [
['Иванов', 'бухгалтер'],
['Денисов', 'инженер'],
]
for employee_name, employee_post in employee:
label = 'Имя: { employee_name }. Должность: { employee_post }'.format(
employeу_name = employeу_name
employee_post = employee_post
)
print(label) # SyntaxError
Код кажется простым и понятным, но в нем скрыта едва заметная ошибка, которая не даст коду запуститься. Пример показывает, что простая запятая легко сломает программу. Естественно, в интерпретированной среде python выдает ошибку, особенно настолько элементарную. Ошибка SyntaxError иногда преследует программиста, когда меняют функции внутри библиотеки, или он просто утомился. В остальном это беда новичков, которые только знакомятся с языком и его синтаксисом.

Недостаточно памяти (OutofMemoryError)
Ошибки python вроде нехватки памяти далеко не редки, причин на то очень много. Разберём три основные:
Сам язык Питон очень ресурсоемкий язык, он однопоточный и при неграмотном подходе способен быстро забрать всю выделенную память устройства.
Утечка данных – переменные в Питон ссылочного типа и в теории он их удаляет, как только они ему не нужны. Но вполне можно организовать ситуацию, когда данные не будут удаляться и постепенно забьют все свободную память.
Бесконечные циклы – когда условия выхода из цикла никогда не наступят, в какой-то момент выделяемая память просто закончиться.
Ошибка рекурсии (RecursionError)
Рекурсия сам по себе не самый безопасный подход, но благодаря ей можно значительно облегчить код. Типы ошибок python вроде RecursionError, по сути, это срабатывание защиты внутри самого языка. Программисту выходят предупреждения, что, вероятно, запустил бесконечную рекурсию и выделенные под предел достигнут.
Простой пример бесконечной рекурсии:
def recurs():
recurs()
recurs() # RecursionError
Ошибка отступа (IndentationError)
Виды ошибок в Питоне вроде неправильных отступов, опять же можно отнести к ошибкам новичков. В Python теле любого логического процесса обозначается четырьмя пробелами. Если есть «:», а внизу на том же уровне идет код — это явная ошибка.
Пример такой явной ошибки:
def spaceBar():
pass
spaceBar() # IndentationError
Типы исключений
Исключения позволяют застраховаться программисту от вероятных неисправностей. Более того, становиться возможным отладить и исправить программу на разных этапах разработки. Обработка исключений в Питон можно назвать фундаментальным навыком, необходимым для развития python разработчика.
Исключение берет свою основу от BaseException, базового исключения от которого наследуются все остальные, именно этот базовый класс позволяет создавать собственные исключения.
Наследуясь от базового класса, исключения делятся на:
- SystemExit
- KeyboardInterrupt
- GeneratorExit
- Exception
Exception единственное несистемное исключение, с которым работает программист. От этого класса идут следующие виды исключений.
Ошибка типа (TypeError)
Один из довольно распространённых типов ошибок проследить все цепочку наследования легко: BaseException, Exception, TypeError. Данное исключение сработает, когда указанный тип данных не существует.
Ошибка деления на ноль (ZeroDivisionError)
Очень часто встречающаяся ошибка при различных делениях. Питон динамичен, но строго типизирован. Так в простой математике делить на ноль нельзя, но ситуация с таким делением может возникнуть по очень многим причинам. Python 3 исключения такого типа сработает к таком элементарном коде:
print( 0 / 0 ) # ZeroDivisionError

Встроенные исключения
Встроенные исключения – это виды ошибок в Питоне, условия исполнения которых четко прописаны в языке. Здесь можно вспомнить деление на ноль, отсутствие или лишние пробелы.
Ошибка прерывания с клавиатуры (KeyboardInterrupt)
Системное исключение KeyboardInterrupt дает прерывание программы какой-то клавишей или сочетанием клавиш, по умолчанию используется Ctrl+C. Это удобный способ прервать, к примеру, бесконечный цикл, когда явно программа работает неправильно.
Как обрабатывать исключения в Python (try except)
Стандартно в Python 3-я обработка исключений строится на try – except, эта конструкция очень часто встречающийся в разных языках программирования. Код обработки исключения выглядит так:
try: # место кода, где возможно срабатывание исключения
a= 10 / 0 # Явная арифметическая ошибка попадает в исключение ZeroDivisionError
except ZeroDivisionError: # Попадаем в исключение сработал ZeroDivisionError
a = 10 / 2 # Операция без ошибок
print( a ) # 5.0 – при делении получаем вещественное число
As — сохраняет ошибку в переменную
В Python try except текст ошибки выводится не через класс, а через экземпляр класса. Для примера попробуем узнать, какая ошибка произошла в коде:
try:
a= 10 - '10'
except Exception:
a = Exception
print( a )
В теории мы ожидаем получить текс ошибки, но результат выполнения программы будет «». Знакомый с языком программирования человек сразу поймет, что он получил не ошибку, а ссылку на класс.
Нам необходимо создать экземпляр класса. Для этого в «except» добавляется «as». Попробуем через try except python вывести ошибку правильно:
try:
a= 10 - '10'
except Exception as Ex:
a = Ex
print( a ) # unsupported operand type(s) for -: 'int' and 'str'
Теперь мы получаем текст о сработавшем исключении с пояснением ошибки.
Finally — выполняется всегда
Finally в конструкции try – except работает так же, как, например, в более знакомом программистам if – else. Попробуем разобрать на примере:
try:
a= 10 - '1' # Явная ошибка вычитания из числа строки
# a= 10 – 1 # Пример без ошибки
except Exception as Ex:
a = Ex
finally: #Все ниже сработает при любом результате
if type (a) == int: #Если все нормально сработало и мы получили число
print( f'получен результат: {a}' )
else:
print( f'произошла ошибка: {a}' )
Блок finally выполнится при любом результате работы программы, сработало или не сработало исключение.
Else — выполняется, когда исключение не было вызвано
Если except python вывод ошибки, то else это обработка, когда ошибки не произошло. Попробуем придумать пример для демонстрации:
try:
a = 10 – 1
#a = 10 - '1' # если захотим проверить пример с ошибкой
except Exception as Ex:
a = Ex
else: # код сработает только, если никаких ошибок не было
a = a * 2
finally:
print( a )
Несколько блоков except
Чем сложнее программа, тем с большим количеством ошибок приходится встречаться. Базовый try except python 3 вывести ошибку не только одним блоком. Except может быть столько, сколько возможных исключений допустимо. Попробуем реализовать в программе:
try:
a = int( input( 'Введите число : ' ))
b = 100 / a
except ZeroDivisionError:
b = 'деление на ноль'
except ValueError:
b = 'ошибка несоответствия типов'
except Exception:
b = 'что-то пошло не так'
print( f'результат работы программы : {b}' )
В примере мы пытаемся поймать сразу два вида исключений, как весьма вероятных. Пользователь может ввести не число или ноль. На крайний случай у нас есть общий класс Exception, который поймает любую другую ошибку.
Несколько типов исключений в одном блоке except
В целом исключения определённого типа вполне возможно группировать. Здесь нет жестких ограничений. Попробуем в python try except вывести текст ошибки на примере кода:
try:
a = int(input('Введите число : '))
b = 100 / a
except (ZeroDivisionError, ValueError):
b = 'Введено недопустимое значение'
except Exception:
b = 'что-то пошло не так'
print( результат работы программы : {b}' )

В примере мы объединяем два типа ошибки, которые делают дальнейшее использование переменой недопустимым.
Raise — самостоятельный вызов исключений
Исключения возможно вызвать самостоятельно, более того, дополняя информацию о событии. Создадим пример, в котором выявим искусственное исключение:
try:
raise Exception("произошла ошибка")
except Exception as e:
print("В программе есть событие : " + str(e))
Встречаясь с raise функция или программа идет к ближайшему except Exception. Так можно не только обработать ошибку, но прописать в каком блоке кода ошибка произошла.
Как пропустить ошибку
Для программиста в python try except вывести текст ошибки важно, но не обязательно. Ошибку можно банально пропустить не пропустить без вреда для кода, рассмотрим пример:
a = 5
try:
a = a / 0
except Exception:
pass
print(a)
В примере есть ошибка, но мы просто пропускаем без вреда для кода.
Стандартные ошибки (StandardError)
С большинством ошибок, существующих в Питоне, программист никогда не встретится, многие из них встречаются в реальных проектах слишком редко. Рассмотрим, какая в python 3 обработка ошибок часто встречается.
Арифметические ошибки (ArithmeticError)
Класс, предназначенный для обработки арифметических ошибок, от него наследуются три класса:
FloatingPointError
– неудачное выполнение операций с вещественными числами. На практике редко встречается.
OverflowErro
– результат математической операции — слишком большое число, обычно это вещественное число.
ZeroDivisionError
– операция приводит к делению на ноль.
Ошибка утверждения (AssertionError)
– класс ошибки, срабатывающий если работа функции assert возвращает ложное утверждение.
Ошибка атрибута (AttributeError)
– класс ошибок, происходящих с отсутствием атрибута функций или методов.
Ошибка импорта (ModuleNotFoundError)
– ошибка, говорящая об отсутствии установленного модуля или пакета
Ошибка поиска (LookupError)
– исключение, срабатывающее при обращении к ключу или индексу несуществующему у объекта.
Ошибка ключа
– исключение срабатывает при обращении внутри словаря к несуществующему внутри него ключу.
Ошибка индекса
– срабатывает когда указанный индекс в объекте типа словарь не существует.
Ошибка памяти (MemoryError)
– в python 3 обработка ошибок срабатывающее, когда памяти для работы программы не хватает или память переполнена.
Ошибка имени (NameError)
– связана с тем, что указываемое название переменой, класса или функции не существует.
Ошибка выполнения (Runtime Error)
– класс ошибок обозначающий, что выполнение функций невозможно или произошла ошибка при выполнении.
Ошибка типа (TypeError)
– исключение, связанное с указанием или использованием неверного типа данных.
Ошибка значения (ValueError)
– исключение чаше встречающееся во время невозможности преобразования типов данных.
Пользовательские исключения в Python
Программист может создать собственный вариант исключений, наследуясь от Exception. Тут стоит обдумывать причины срабатывания и как вывести ошибку python. Код будет выглядеть примерно так:
class MyException(Exception):
pass
try:
val = int(input("Введите число: "))
if val < 0:
raise MyException("Число меньше нуля: " + str(val))
print(val + 10)
except MyException as e:
print(e)
Недостатки обработки исключений в Python
Базовые проблемы питона перекочевали в обработчик исключений, динамичность, множественное наследование, большой расход ресурсов. Также стоит отметить, что try except python в одну строку написать практически невозможно, без потери функциональности. В целом любая проблема решаема, главное — продумывать, как и когда использовать исключение.
Заключение
Не существует программиста, который способен писать код сразу, идеально, без малейших дефектов и уязвимостей. Python часто называют языком для новичков, но это не значит, что язык сделает все сам или додумает то, что не прописано. Исключения помогают избежать определённые ситуаций, не всех, но многих. Стоит помнить, что никакая дополнительная функция ошибок python не учит не совершать их вновь.