В этой главе мы изучим исключения в Python и как обрабатывать их в вашем коде.

NameError

Когда начинаешь писать код, это будет одно из самых частых исключений, с которым ты столкнешься. Это происходит, когда кто-то пытается получить доступ к переменной, которая не определена.

>>> print(kushal)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'kushal' is not defined

Последняя строка содержит детали сообщения об ошибке, остальные строки показывают подробности того, как это произошло (или что вызвало это исключение).

TypeError

TypeError также является одним из наиболее часто встречающихся исключений. Это происходит, когда кто-то пытается выполнить операцию с несовместимыми типами данных. Распространенный пример — это сложение целых чисел и строки.

>>> print(1 + "кушал")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: неподдерживаемые типы операндов для +: 'int' и 'str'

Как обрабатывать исключения?

Мы используем блоки try…except для обработки любых исключений. Основной синтаксис выглядит следующим образом:

try:
    statements to be inside try clause
    statement2
    statement3
    ...
except ExceptionName:
    statements to evaluated in case of ExceptionName happens

Он работает следующим образом:

  • Сначала выполняются все строки между try и except операторами.
  • Если возникает ExceptionName во время выполнения операторов, то выполняются операторы в блоке except.
  • Если исключение не возникает, то операторы внутри блока except не выполняются.
  • Если Exception не обрабатывается в блоке except, то оно выходит за пределы блока try.

Следующие примеры демонстрируют эти сценарии.

>>> def get_number():
...     "Returns a float number"
...     number = float(input("Enter a float number: "))
...     return number
...
>>>
>>> while True:
...     try:
...         print(get_number())
...     except ValueError:
...         print("You entered a wrong value.")
...
Enter a float number: 45.0
45.0
Enter a float number: 24,0
You entered a wrong value.
Enter a float number: Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
  File "<stdin>", line 3, in get_number
KeyboardInterrupt

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

В третий раз я нажал Ctrl+c, что вызвало KeyboardInterrupt, который не обрабатывается в блоке except, поэтому выполнение остановилось с этим исключением.

Пустой оператор except может перехватывать любое исключение. Прочитайте следующий пример:

>>> try:
...     input() # Press Ctrl+c for a KeyboardInterrupt
... except:
...     print "Unknown Exception"
...
Unknown Exception

Вызов исключений

Исключение можно вызвать с помощью оператора raise.

>>> raise ValueError("Произошла ошибка значения.")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Произошла ошибка значения.

Мы можем перехватывать эти исключения как любые другие обычные исключения.

>>> try:
...     raise ValueError("Произошла ошибка значения.")
... except ValueError:
...     print("Ошибка ValueError в нашем коде.")
...
Ошибка ValueError в нашем коде.

Использование finally для очистки

Если мы хотим, чтобы некоторые инструкции выполнялись при любых обстоятельствах, мы можем использовать предложение finally, оно будет выполняться всегда перед завершением инструкций try.

>>> try:
...     fobj = open("hello.txt", "w")
...     res = 12 / 0
... except ZeroDivisionError:
...     print("У нас ошибка деления на ноль")
... finally:
...     fobj.close()
...     print("Закрытие файлового объекта.")
...
У нас ошибка деления на ноль
Закрытие файлового объекта.

В этом примере мы уверены, что файловый объект, который мы открываем, будет закрыт в предложении finally.

Перейти к следующему уроку →