Посмотреть все уроки курса
Выбрать другой урок из курса
Поиск по сайту
Теория урока

10.5. Обработка исключений (try/except) в Python

Оглавление урока

Введение

В предыдущем уроке вы познакомились с циклами while/else и for/else. В этом уроке разберем, как обрабатывать исключения, вызываемые интерпретатором Python. Уверен, вы писали код, который отлично работал, но при вводе определенных данных, например, строки вместо числа, программа останавливалась и выдавала ошибку. Это генерировалось исключение и, так как вы его не обрабатывали, работа программы прекращалась.

Давайте целенаправленно вызовем исключение ZeroDivisionError. Если вы разделите любое число на ноль, то получите подобную ошибку:

Пример
Traceback (most recent call last):
  File "C:/test.py", line 1, in <module>
    print(5/0) 
ZeroDivisionError: division by zero       

Этим сообщением интерпретатор Python нам говорит об ошибке в первой строке файла test.py, а точнее, в выражении print(5/0). В последней строке ошибки содержится название исключения и ее краткое описание.

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

Теперь кратко рассмотрим некоторые из исключений, которые могут возникнуть в языке Python. Сразу оговорюсь, нет необходимости запоминать все эти исключения, так как всегда их можно посмотреть в справочнике или здесь. С другой стороны, знание возможных ошибок поможет их предвидеть и не допустить. Материал этого раздела находится под спойлером, так как получился объемным.

BaseException – это базовое исключение, от него берут начало все остальные исключения.

В базовое исключение входят:

  • GeneratorExit: будет вызвано в случае применения метода close, объекта generator.
  • SystemExit: будет вызвано функцией sys.exit в случае выхода из программы.
  • KeyboardInterrupt: будет вызвано, если пользователь нажал сочетание клавиш Ctrl + C в консоли.
  • Exception: в отличие от предыдущих, это группа не системных исключений, а «пользовательских», если так можно выразиться.
СПОЙЛЕР. Более подробно про класс исключений Exception

Исключения Exception

Группа исключений Exception подразделяется на следующие:

Группа исключений ArithmeticError

Исключения, связанные с арифметическими ошибками. Исключение FloatingPointError связано с выполнением неудачной операции с плавающей точкой. Исключение OverflowError возникает, когда результат арифметической операции слишком большой и не может быть представлен. Исключение ZeroDivisionError возникает из-за деления на ноль. Для примера, следующий код не будет работать, так как будет вызвано исключение OverflowError:

Пример
pi = 0
for k in range(350):
    pi += 16.**k
print(pi)       

Исключение AssertionError

Вызывается, если результат проверки инструкции assert является ложным. Например:

Пример
assert 1 == 0       

К инструкции assert мы еще вернемся.

Исключение AttributeError

Возникает, если у объекта нет такого атрибута или в случае ошибки доступа к нему. Например:

Пример
a = 10
a.atr       

Так как переменная (объект) a не имеет атрибута atr, то будет вызвано исключение:

Пример
Traceback (most recent call last):
  File "C:/test.py", line 2, in <module>
    a.atr()
AttributeError: 'int' object has no attribute 'atr'        

Исключение BufferError

Возникает, когда операция с буфером не может быть выполнена по тем или иным причинам. Например, буфер не доступен для записи, так как работает только в режиме «для чтения».

Исключение EOFError

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

Исключение ImportError

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

Группа исключений LookupError

Исключение IndexError вызывается, если используемый индекс выходит за диапазон, например, обратимся к четвертому списка из трех элементов:

Пример
a = [1, 2, 3]
a[3]       

Исключение KeyError возникает, если вы обратились к несуществующему ключу:

Пример
a = {'1': 1, '2': 2, '3': 3}
a['4']       

Исключение MemoryError

Возникает, если закончилась память при выполнении операции.

Исключение NameError

Возникает, если не найдено имя переменной, функции или другого объекта, например:

Пример
print(a)       

Результат:

Пример
Traceback (most recent call last):
  File "C:/test.py", line 1, in <module>
    print(a)
NameError: name 'a' is not defined       

Группа исключений OSError

Большая по своему составу группа исключений, связанных с системой.

В нее входит исключение BlockingIOError, которое поднимается, когда блокируется ввод/вывод. Исключение ChildProcessError возникает при неудачной операции с дочерним процессом. Исключение ConnectionError является еще одной группой, связанной с проблемами подключения. Исключение FileExistsError будет поднято, если вы попытаетесь создать уже существующий файл или директорию. Исключение FileNotFoundError возникнет, если вы обратитесь к несуществующему файлу или директории. Если системный вызов был прерван каким-либо входящим сигналом, то поднимется исключение InterruptedError. Исключение IsADirectoryError возникнет, если интерпретатор Python ожидал файл, но это оказалась директория. Исключение NotADirectoryError является противоположным предыдущему. Если возникли проблемы с правами доступа, то поднимется исключение PermissionError. Исключение ProcessLookupError возникнет, если такого процесса не существует, а TimeoutError, если закончилось время ожидания.

Исключение ReferenceError

Исключение ReferenceError поднимается в случае обращения к атрибуту объекта с помощью слабой ссылки. Тема про слабые ссылки не такая простая, но, возможно, мы к ней вернемся. Если кратко: слабые ссылки нужны для организации хэш-таблиц из «увесистых» объектов. За работу слабых ссылок отвечает модуль weakref.

Исключение RuntimeError

Такое исключение возникает в связи с ошибкой времени исполнения не попадающей под другие категории. До версии Python 3.5. под это исключение попадала бесконечная рекурсия, однако сейчас под это выделен новый тип исключений: RecursionError.

Исключение StopIteration

Поднимается функцией next, если в итераторе закончились элементы. Про итераторы мы поговорим в последующих уроках.

Исключение SyntaxError

Наверное, с исключением SyntaxError вы будете встречаться чаще всего. Оно поднимается парсером в случае нахождения синтаксических ошибок в исходном коде.

Исключение SystemError

Поднимается, когда возникают внутренние ошибки на уровне интерпретатора.

Исключение TypeError

Исключение TypeError поднимается при попытке обработки объекта, для которого такие действия неприменимы. Например, сложение строки и числа:

Пример
print('Hello' + 20)       

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

Исключение ValueError

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

Группа исключений Warning

Исключения группы Warning связаны с различными категориями предупреждений.

Конструкция try/except в Python

Настало время перейти к конструкции, которая позволяет «отлавливать» исключения в Python. Предположим, у нас есть программа, на вход которой поступает два числа, после чего одно делится на другое.

Пример
a, b = int(input()), int(input())
print(a / b)       

Вы уже знаете, что при определенных входных данных, программа завершится. Конечно, от деления на ноль можно защититься при помощи условной конструкции if:

Пример
a, b = int(input()), int(input())
if (b != 0):
    print(a / b)
else:
    print("b равно 0")       

Перепишем этот пример с использованием инструкции try/except:

Пример
try:
    a, b = int(input()), int(input())
    print(a / b)
except ZeroDivisionError:
    print("b равно 0")       

Как же работает инструкция try/except? Сначала будет выполнено выражение, которое расположено в блоке try. Если внутри блока try не возникло никаких исключений, то блок except пропускается и выполняется дальнейший код.

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

Пример
try:
    a, b = int(input()), int(input())
    print(a / b)
except ZeroDivisionError:
    print("b равно 0")
print("Конец программы")       

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

Пример
try:
    a, b = int(input()), int(input())
    print(a / b)
except ZeroDivisionError:
    print("b равно 0")
except ValueError:
    print("Введите число")       

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

Пример
try:
    a, b = int(input()), int(input())
    print(a / b)
except (ZeroDivisionError, ValueError):
    print("Ошибка в работе программы.")       

Конструкция try/except поддерживает возможность перехватывать все исключения, для этого можно не указывать тип:

Пример
try:
    a, b = int(input()), int(input())
    print(a / b)
except:
    print("Ошибка в работе программы.")       

Конструкция try/except в Python имеет еще два опционных блока: finally и else. Блок finally выполняется всегда, независимо от того, было исключение или нет. Снова может показаться, что это бесполезный блок, ведь если except будет ловить все ошибки, то последующий код будет без проблем выполняться. Приведу пример, когда блок finally действительно необходим:

Пример
import sys

try:
    while True:
        pass
except KeyboardInterrupt:
    print('Ctrl + C')
    sys.exit()
finally:
    print("Выполнение чего-то важного")
print("Конец программы")       

Программа будет закрыта только при помощи сочетания клавиш Ctrl + C. Запустите пример и убедитесь что последний print() будет пропущен. А что если перед закрытием программы при помощи сочетания клавиш Ctrl + C необходимо сохранить пользовательскую информацию? Блок finally в данном случае вас выручит.

Опционный блок else в конструкции try/except нужен, чтобы выполнить необходимые инструкции только в том случае, если исключения не вызывались. Далее пример:

Пример
try:
    a, b = int(input()), int(input())
    print(a / b)
except:
    print("Ошибка в работе программы.")
else:
    print("Конец программы")       

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

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

Пример
try:
    a, b = int(input()), int(input())
    print(a / b)
except Exception as e:
    print(f"Исключение: {type(e)}")
    print(f"Что случилось: {e}")       

В этом примере мы используем f-строки и функцию type(). Если про них забыли, то вернитесь к этим урокам чтобы освежить в памяти. К ключевому слову as мы еще вернемся, когда будем работать с файлами.

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

Иногда необходимо сгенерировать исключение, можно использовать ключевое слово raise:

Пример
try:
    a, b = int(input()), int(input())
    if (b == 0):
        raise ZeroDivisionError
    print(a / b)

except ZeroDivisionError:
    print("Деление на ноль")       

Или вы можете вызвать свое исключение в виде текстового сообщения:

Пример
try:
    a, b = int(input()), int(input())
    if (b == 0):
        raise ValueError("Деление на ноль")
    print(a / b)

except Exception as e:
    print(e)       

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

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

Инструкцию assert рекомендуется использовать для проверки ситуаций, которые не должны происходить, то есть те, которые нельзя обработать.

Заключение

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

В этом уроке мы научились обрабатывать ошибки в Python при помощи конструкций try/except, try/except/else и try/except/finally. Узнали, как возбудить свою ошибку при помощи ключевого слова raise. Кратко узнали о ключевом слове as и утверждении assert.

Перед обработкой исключений, оцените как проще и эффективней предупредить ошибку: использовать try/except или обычную условную конструкцию if.

<
×
>
Раздел «Знакомство с Python»
Урок 1.1. Первое знакомство с Python
Тест 1.2. Небольшой первый тест
Урок 1.3. Переменные и комментарии в Python
Тест 1.4. Тест по основным понятиям и работе с сайтом
Урок 2.1. Погружение в Python
Тест 2.2. Второй вводный тест по Python
Урок 2.3. Типы данных в Python
Урок 2.4. Форматирование строк в Python
Урок 2.5. Условная инструкция if-elif-else в Python
Урок 2.6. Преобразование и проверка типов в Python
Урок 2.7. Вызов методов цепочкой в Python
Урок 3.1. Первое знакомство с циклами в Python
Тест 3.2. Тест по циклам Python
Урок 4.1. Генерируем случайные числа на Python
Тест 4.2. Тест по модулю random Python
Урок 5.1. Структуры данных в Python
Тест 5.2. Тест по структурам Python
Урок 6.1. Списки в Python
Тест 6.2. Тест по спискам Python
Урок 6.3. Изменение списка на месте в Python
Урок 6.4. Дополнительно про списки в Python
Урок 6.5. Конкатенация и сортировка списков в Python
Тест 6.6. Заключительный тест по спискам в Python
Урок 7.1. Словари в Python
Тест 7.2. Тест по словарям Python
Урок 7.3. Словари и списки: еще глубже
Урок 7.4. Перебор элементов словаря в Python
Урок 7.5. Внутреннее устройство и сортировка словаря в Python
Урок 7.6. Методы словарей и функция len() в Python
Тест 7.7. Заключительный тест по словарям
Урок 8.1. Множества в Python
Урок 8.2. Методы и особенности множеств в Python
Урок 8.3. Отношения между множествами и операции над ними
Тест 8.4. Тест по методам множеств в Python
Тест 8.5. Тест по операциям над множествами в Python
Урок 9.1. Кортежи в Python
Урок 9.2. Более подробно о кортежах в Python
Тест 9.3. Тест по кортежам в Python
Урок 10.1. Контроль хода выполнения программы в Python
Урок 10.2. Цикл while в Python
Урок 10.3. Операторы break, continue и pass в Python
Урок 10.4. Циклы for/else и while/else в Python
Урок 10.5. Обработка исключений (try/except) в Python
Вы здесь
Тест 10.6. Тест по циклам и управляющим конструкциям
Тест 10.7. Тест по обработке исключений
Урок 10.8. Что дальше?