Для лучшего понимания этого раздела, рекомендуем ознакомиться с общими приемами обработки исключений и использованием инструкции finally
.
В конструкция try/except/else/finally
определяется обработчики исключений и/или код очистки для группы операторов.
except
.В инструкциях except
указывается один или несколько обработчиков исключений. Если в коде между инструкциями try/except
не возникает исключения, то обработчик исключений не выполняется. При возникновении исключения в коде между инструкциями try/except
запускается поиск обработчика исключения. Этот поиск проверяет выражения во всех инструкциях except
по очереди, пока не будет найден тот, который соответствует исключению.
Инструкция except
без выражения, если она присутствует, должна быть последней. Она соответствует любому встроенному исключению.
import sys try: f = open('myfile.txt') s = f.readline() i = int(s.strip()) except OSError as err: # содержит выражение OSError as err print("OS error: {0}".format(err)) except ValueError: # содержит выражение ValueError print("Не удалось преобразовать данные в целое число.") except: # инструкция 'except' без выражения print("Непредвиденная ошибка:", sys.exc_info()[0])
Для инструкций except
с выражением - выражение оценивается и сравнивается с брошенным исключением в коде, между инструкцией try
и первым except
. Выражение соответствует исключению в том случае, если результирующий объект выражения "совместим" с исключением. Объект выражения совместим с исключением, если это класс или базовый класс объекта исключения или кортеж, содержащий элемент, совместимый с исключением.
try: ... except (OSError, ValueError): # инструкция 'except' содержит # кортеж возможных исключений ...
Если исключению не соответствует выражению, указанному в инструкции except
, то поиск обработчика исключения продолжается в окружающем коде и в стеке вызовов.
Если вычисление выражения в заголовке инструкции except
вызывает исключение, то исходный поиск обработчика отменяется и начинается поиск нового исключения в окружающем коде и в стеке вызовов. Другими словами, такая ситуация обрабатывается так, как если бы вся цепочка инструкций try
вызвала исключение.
Если найдено соответствующее выражение в инструкции except
, то исключение назначается целевому объекту, указанному после ключевого слова as
в этом выражении, если конечно as
присутствует, далее выполняется блок кода выбранной инструкции except
. Все инструкции except
должны иметь исполняемый блок кода. Когда достигается конец выбранного блока, выполнение кода продолжается после выполнения всей инструкции try
. Это означает, что если существуют два вложенных обработчика для одного и того же исключения и исключение возникает в предложении try
внутреннего обработчика, то внешний обработчик не будет обрабатывать исключение.
Когда исключение было назначено с помощью выражения as target
, то переменная target
очищается в конце предложения except
. Это как если бы:
except E as N: foo
был переведен на:
except E as N: try: foo finally: del N
Следовательно, если надо сослаться на исключение target
после инструкции except
, то необходимо исключению в target
присвоить другой переменной. Исключения очищаются, так как с присоединенной к ним обратной трассировкой они образуют ссылочный цикл с кадром стека, сохраняя все локальные объекты в этом кадре живыми до следующей сборки мусора.
Перед выполнением блока кода инструкции except
, сведения об исключении сохраняются в модуле sys
и могут быть доступны через sys.exc_info()
. Метод sys.exc_info()
возвращает тройной кортеж, состоящий из класса исключения, экземпляра исключения и объекта трассировки, идентифицирующего точку в программе, где произошло исключение. Значение метода sys.exc_info()
восстанавливаются до своих предыдущих значений (до вызова) при возврате из функции, которая обработала исключение.
else
.Необязательная инструкция else
выполняется, только если поток управления покидает блок кода между try/except
, не вызвав исключения и если не было выполнено ни одного оператора return
, continue
или break
в этом блоке кода.
Исключения в блоке кода else
не обрабатываются предыдущими инструкциями except
.
finally
.Если в конструкции try
присутствует инструкция finally
, то она определяет обработчик 'cleanup'
. Оператор try
выполняет все инструкции, включая except
и else
. Если исключение возникает в любой из этих инструкции и не обрабатывается, то исключение временно сохраняется. При исполнении инструкции finally
, если существует сохраненное исключение, оно повторно вызывается после выполнения блока кода инструкции finally
. Если finally
вызывает другое исключение, то сохраненное исключение устанавливается как контекст нового исключения. Если инструкция finally
выполняет оператор return
, break
или continue
, то сохраненное исключение отбрасывается:
def f(): try: 1/0 finally: return 42 >>> f() # 42
Информация об исключении недоступна программе во время выполнения инструкции finally
.
Когда операторы return
, break
или continue
выполняется в блоке кода инструкции try
конструкции try/finally
, блок кода инструкции finally
также выполняется ‘на выходе.’
Возвращаемое значение функции определяется последним выполненным оператором return
. Поскольку инструкция finally
выполняется в любом случае, оператор return
, выполняемый в блоке кода инструкции finally
, всегда будет последним выполненным:
def foo(): try: return 'try' finally: return 'finally' >>> foo() # 'finally'
Дополнительную информацию об исключениях можно найти в материалах "Ошибки выполнения программы" и "Обработка исключений в Python", а информацию об использовании инструкции raise
генерации исключений можно найти в материале "Инструкция raise в Python"