Обработка исключений¶
Существует два типа ошибок, которые обычно возникают при написании программы. Первый известен как синтаксические ошибки, когда программист ошибается в написании структуры оператора или выражения. Вот пример неправильно написанного оператора и пропущенного двоеточия:
>>> for i in range(10)
SyntaxError: invalid syntax (<pyshell#61>, line 1)
В этом случае интерпретатор Python находит, что не может выполнить эту инструкцию до тех пор, пока она не будет удовлетворять языковым правилам. Чаще всего синтаксические ошибки встречаются, когда вы только начинаете изучать новый язык программирования.
Другой тип ошибок, известный как логические ошибки, имеет отношение к тем ситуациям, когда код выполняется, но выдаёт неправильный результат. Причиной может быть ошибка в основном алгоритме или неверная трансляция вами этого алгоритма. В некоторых случаях логические ошибки приводят к очень плохим ситуациям: делению на нуль или попыткам получить доступ к элементу списка, чей индекс выходит за списковые границы. В таком случае логическая ошибка влечёт за собой ошибку времени выполнения, которая вызывает завершение программы. Ошибки такого типа во время выполнения обычно называют исключениями.
Большую часть времени начинающие программисты думают об исключениях, как о фатальных ошибках во время выполнения, приводящих экстренному завершению программы. Однако, большинство языков программирования предоставляют способ иметь дело с такого рода ошибками, что позволяет программисту вмешиваться в процесс, если он того пожелает. Более того, программисты могут создавать свои собственные исключения, если они обнаруживают в программе ситуацию, когда это может быть оправдано.
When an exception occurs, we say that it has been “raised.” You can “handle” the exception that has been raised by using a try statement. For example, consider the following session that asks the user for an integer and then calls the square root function from the math library. If the user enters a value that is greater than or equal to 0, the print will show the square root. However, if the user enters a negative value, the square root function will report a ValueError exception.
Когда возникает исключение, мы говорим, что оно “вызывается”. Вы можете “обработать” вызванное исключение, используя оператор <code>try</code>. Рассмотрим, например, следующий код, который запрашивает у пользователя целое число, а затем вызывает функцию извлечения квадратного корня из математической библиотеки. Если пользователь вводит значение, которое больше или равно нулю, print выведет квадратный корень. Однако, если пользователь введёт отрицательное значение, то функция квадратного корня сообщит об исключении ValueError.
>>> anumber = int(input("Please enter an integer "))
Please enter an integer -23
>>> print(math.sqrt(anumber))
Traceback (most recent call last):
File "<pyshell#102>", line 1, in <module>
print(math.sqrt(anumber))
ValueError: math domain error
>>>
Мы можем обработать это исключение, вызвав функцию print внутри try блока. Соответствующий except-блок “поймает” исключение и напечатает сообщение пользователю, в котором сообщит о возникновении исключения. Например:
>>> try:
print(math.sqrt(anumber))
except:
print("Bad Value for square root")
print("Using absolute value instead")
print(math.sqrt(abs(anumber)))
Bad Value for square root
Using absolute value instead
4.79583152331
>>>
поймает тот факт, что при выполнении sqrt возникло исключение, напечатает сообщение об этом пользователю и возьмёт абсолютное значение аргумента, чтобы быть уверенным в его неотрицательности. Всё вместе это означает, что программа не завершится, а продолжит выполнение следующих операторов.
У программиста также существует возможность искусственно вызвать исключение во время выполнения, используя оператор raise. Например, вместо вызова функции квадратного корня для отрицательного числа, мы прежде можем проверить значение и вызвать наше собственное исключение. Код ниже показывает результат создания нового исключения RuntimeError. Заметьте, что программа по-прежнему будет завершаться, но теперь исключением, вызывающим такое поведение, является нечто явно созданное программистом.
>>> if anumber < 0:
... raise RuntimeError("You can't use a negative number")
... else:
... print(math.sqrt(anumber))
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
RuntimeError: You can't use a negative number
>>>
Существует множество типов исключений кроме показанного выше RuntimeError , которые могут быть вызваны. Смотрите ссылку на руководство по Python, где представлены список всех доступных типов исключений и инструкция по созданию своих собственных.