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

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

Перехват и возбуждение исключений

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

try:
    try_suite
except exception_group1 as variable1:
    except_suite1
...
except exception_groupN as variableN:
    except_suiteN
else:
    else_suite
finally:
    finally_suite

Эта конструкция должна содержать хотя бы один блок except, а блоки else и finally являются необязательными. Блок else_suite выполняется, только если блок try_suite завершается обычным способом, и не выполняется в случае возникновения исключения. Если блок finally присутствует, он выполняется всегда и в последнюю очередь.

Каждая группа exception_group в предложении except может быть единственным исключением или кортежем исключений в круглых скобках. Часть as variable в каждой группе является необязательной. В случае ее использования в переменную variable записывается ссылка на исключение, которое возникло, благодаря этому к нему можно будет обратиться в блоке except_suite.

Если исключение возникнет во время выполнения блока try_suite, интерпретатор поочередно проверит каждое предложение except. Если будет найдена соответствующая группа exception_group, будет выполнен соответствующий блок except_suite. Соответствующей считается группа, в которой присутствует исключение того же типа, что и возникшее исключение, или возникшее исключение является подклассом одного из исключений, перечисленных в группе.

На рис. 1 демонстрируется порядок выполнения типичной конструкции try ... except ... finally.


Рисунок 1: Порядок выполнения конструкции try ... except ... finally

Ниже приводится окончательная версия функции list_find(), на этот раз она использует механизм обработки исключения:

def list_find(lst, target):
    try:
        index = lst.index(target)
    except ValueError:
        index = -1
    return index

Здесь мы использовали конструкцию try ... except для преобразования исключения в возвращаемое значение. Аналогичный подход можно использовать для перехвата одних исключений и возбуждения других – с этим приемом мы познакомимся очень скоро.

Возбуждение исключений

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

raise exception(args)
raise

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