Это седьмая часть из 14 серий нетрадиционного введения в Python, написанного с целью научиться продуктивно использовать вычислительные методы. Ссылки на все части смотрите в первой статье

«Исключение» обычно определяется как «что-то, что не соответствует норме», и поэтому встречается довольно редко. Однако в исключениях в Python нет ничего необычного.
Те читатели (мы надеемся, что все вы), которые пытались писать и запускать программы на Python, уже сталкивались со многими из них. Среди наиболее часто встречающихся типов исключений — TypeError, NameError и ValueError.

Например, откройте оболочку Python и введите

test = [1,2,3]
 test[3]

и интерпретатор ответит что-то вроде

Трассировка (последний последний вызов):
Файл ‹pyshell#1›, строка 1, в ‹module›
test[3]
IndexError: индекс списка вне допустимого диапазона

IndexError — это тип исключения, которое Python вызывает, когда программа пытается получить доступ к элементу, находящемуся за пределами индексируемого типа.

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

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

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

try:
    successFailureRatio = numSuccesses/float(numFailures) 
    print('The success/failure ratio is', successFailureRatio)
except ZeroDivisionError:
    print('No failures so the success/failure ratio is undefined.')
print 'Now here'

При входе в блок try интерпретатор пытается вычислить выражение numSuccesses/float(numFailures). Если вычисление выражения прошло успешно, программа присваивает значение выражения переменной successFailureRatio, выполняет оператор печати в конце блока try и переходит к оператору печати, следующему за оператором try-except.

Однако, если во время вычисления выражения возникает исключение ZeroDivisionError, управление немедленно переходит к блоку except (пропуская присваивание и оператор печати в блоке try), оператор печати в блоке exclude выполняется, а затем выполнение продолжается с оператора печати, следующего за блоком try-except.

Давайте также рассмотрим хорошо обработанную полиморфнуюфункцию readVal, т. е. она работает с аргументами самых разных типов.

def readVal(valType, requestMsg, errorMsg): 
    while True:
               val = raw_input(requestMsg + ' ') 
               try:
                   val = valType(val)
                   return val 
               except ValueError:
                    print(val, errorMsg)

Если блок программного кода может вызвать более одного типа исключений, за зарезервированным словом кроме может следовать кортеж исключений, например, за исключением (ValueError, TypeError):
в этом случае исключение блок будет введен, если какое-либо из перечисленных исключений возникнет в блоке try.

Если программист пишет

except:

блок exclude будет введен, если в блоке try возникнет какое-либо исключение.

Исключения как механизм потока управления

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

def getGrades(fname): 
    try: 
        gradesFile = open(fname, 'r') #open file for reading 
    except IOError:
        raise ValueError('getGrades could not open ' + fname) 
    grades = []
    for line in gradesFile: 
        try: 
            grades.append(float(line)) 
        except:
            raise ValueError('Unable to convert line to float')
return grades
try:
    grades = getGrades('quiz1grades.txt') 
    grades.sort()
    median = grades[len(grades)//2]
    print('Median grade is: '+ median)
except ValueError, errorMsg: 
    print('Whoops.'+errorMsg)

Функция getGrades либо возвращает значение, либо вызывает исключение, с которым она связана со значением. Он вызывает исключение ValueError, если вызов open вызывает IOError. Он мог бы проигнорировать ошибку IOError и позволить той части программы, которая вызывает getGrades, справиться с ней, но это дало бы вызывающему коду меньше информации о том, что пошло не так. Код, использующий getGrades, либо использует возвращенное значение для вычисления другого значения, либо обрабатывает исключение и выводит полезное сообщение об ошибке.

Утверждения

Оператор Python assert предоставляет программистам простой способ подтвердить, что состояние вычислений соответствует ожидаемому. Оператор assert может принимать одну из двух форм:

   assert Boolean expression
or
   assert Boolean expression, argument

Когда встречается оператор assert, вычисляется логическое выражение. Если он оценивается как True, выполнение продолжается своим веселым путем. Если оно оценивается как False, возникает исключение AssertionError.
Утверждения можно использовать, например, для подтверждения того, что промежуточные значения имеют ожидаемые значения или что функция возвращает допустимое значение.

Все кредиты принадлежат профессору Джону Гуттагу, и все ссылки связаны с его вкладом в эту область.

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