Написанная программа на языка Python, при обнаружении ошибки останавливается. Ошибки могут быть двух типов, синтаксические и исключения. В этом руководстве мы поговорим об исключениях Python.
- Синтаксические ошибки — возникают, когда написанное выражение не подчиняется правилам языка (например, пишется лишняя скобка);
- Исключения - возникают при выполнении программы (например, при делении на ноль).
Синтаксические ошибки легко исправить (если вы используете IDE, они будут выделены). А вот с исключениями все немного сложнее — не всегда можно при написании программы сказать, возникнет исключение в данном месте или нет. Чтобы приложение продолжало работать при возникновении проблем, эти ошибки должны быть перехвачены и обработаны с помощью блока try/except.
Как устроен механизм исключений
В Python есть встроенные исключения, которые генерируются после того, как приложение находит ошибку. В этом случае текущий процесс временно приостанавливается и распространяет ошибку до тех пор, пока ее нельзя будет обработать. Если ошибку не обработать, программа перестанет работать (и мы увидим трассировку с подробным описанием ошибки в консоли).
Давайте напишем пример вывода ошибки, где передадим вместо числа строку, и получим ошибку "TypeError"
def num_a(num):
print(type(num))
print(num + 1)
num_a('2')
Результат TypeError:
>>> <class 'str'>
>>> Traceback (most recent call last):
>>> File "C:\Users\Razilator\Desktop\Courses\nth-coding\main.py", line 5, in <module>
>>> num_a('2')
>>> File "C:\Users\Razilator\Desktop\Courses\nth-coding\main.py", line 3, in num_a
>>> print(num + 1)
>>> TypeError: can only concatenate str (not "int") to str
Traceback — это отчет, содержащий вызовы функций, сделанные в определенное время. Трассировка помогает выяснить, что пошло не так и где это произошло.
В нашем примере Traceback содержится следующую информацию (читаем снизу вверх):
TypeError
— тип ошибки (означает, что операция не может быть выполнена с переменной этого типа);can only concatenate str (not "int") to str
— подробное описание ошибки (конкатенировать можно только строку со строкой);most recent call last
— означает, что самый последний вызов будет отображаться последним в стеке (в нашем примере последним выполнилсяprint(num + 1)
).- Стек вызова функций (5-я линия — место, 3-я линия — код). В нашем примере видно, что в файле "main.py" на 5-й линии был вызов функции "
num_a
" со строковым аргументом "2". Далее вызовprint(num + 1)
это последнее, что было выполнено — тут и произошла ошибка.
В Python можно обнаружить ошибку, обработать ее и продолжить выполнение программы: для этого используется конструкция: try... except...
Как обрабатывать исключения в Python (try except)
В Python исключения обрабатываются с помощью блоков try/except
. Для этого в блок try
помещается операция, которая может генерировать исключение. А код, который должен выполняться при возникновении ошибки, находится внутри except
.
Например, вот как обработать ошибку деления на ноль:
try:
a = 8 / 0
except:
print('Ошибка! Деление на 0')
Здесь в блоке try
находится код a = 7 / 0
— при попытке его выполнить возникнет исключение и выполнится код в блоке except
(то есть будет выведено сообщение "Ошибка! Деление на 0"). После этого программа продолжит свое выполнение.
PEP 8 рекомендует, по возможности, указывать конкретный тип исключения после ключевого слова except (чтобы перехватывать и обрабатывать конкретные исключения):
try:
a = 8 / 0
except ZeroDivisionError:
print('Ошибка! Деление на 0')
А можно ловить все исключения:
try:
a = 8 / 0
except Exception:
print('Любая ошибка!')
As — сохраняет ошибку в переменную
Перехваченная ошибка является объектом класса, наследуемого от «BaseException». Используя ключевое слово as, вы можете записать этот объект в переменную, чтобы вы могли ссылаться на него внутри блока исключений:
try:
file = open('notehunter.txt', 'r')
except FileNotFoundError as e:
print(e)
Результат:
>>> [Errno 2] No such file or directory: 'notehunter.txt'
В примере выше мы ссылаемся на объект класса «FileNotFoundError» (при выводе на экран через print будет отображаться строка с полным описанием ошибки).
Finally — выполняется всегда
При работе с исключениями, после блока try
можно использовать блок finally
. Он как except, но код написанный внутри этого блока выполнится обязательно, независимо было ли исключение, или нет.
Обычно try/except
используется для перехвата исключений и восстановления нормальной работы приложения, а try/finally
для того, чтобы гарантировать выполнение определенных действий (например, для закрытия внешних ресурсов, таких как ранее открытые файлы).
file = open('notehunter.txt', 'r')
try:
lines = file.readlines()
print(lines[5])
finally:
file.close()
if file.closed:
print('Файл закрыт')
Результат:
>>> Файл закрыт
>>> Traceback (most recent call last):
>>> File "C:\Users\Razilator\Desktop\Courses\nth-coding\main.py", line 5, in <module>
>>> print(lines[5])
>>> IndexError: list index out of range
Даже после исключения "IndexError", сработал код в секции finally, который закрыл файл.
Else — выполняется когда исключение не было вызвано
Иногда вам нужно предпринять определенные действия, когда код в блоке try не выдал исключение. Для этого используется блок else.
Предположим, вам нужно вывести результат деления двух чисел и обработать исключения в случае попытки деления на ноль:
b = int(input('b = '))
c = int(input('c = '))
try:
a = b / c
except ZeroDivisionError:
print('Ошибка! Деление на 0')
else:
print(f"a = {a}")
Результат:
>>> b = 10
>>> c = 5
>>> a = 2.0
Raise — самостоятельный вызов исключений
Исключения можно генерировать самостоятельно — для этого нужно запустить оператор raise.
min = 300
if min > 10:
raise Exception('min must be less than 10')
Ошибка:
>>> Traceback (most recent call last):
>>> File "C:\Users\Razilator\Desktop\Courses\nth-coding\main.py", line 3, in <module>
>>> raise Exception('min must be less than 10')
>>> Exception: min must be less than 10
Как пропустить ошибку
Иногда ошибку обрабатывать не нужно. В этом случае ее можно пропустить с помощью pass:
try:
a = 8 / 0
except ZeroDivisionError:
pass
20 типов встроенных исключений в Python
Все исключения в Python наследуются от базового BaseException
:
SystemExit
— системное исключение, вызываемое функцией sys.exit() во время выхода из приложения;KeyboardInterrupt
— возникает при завершении программы пользователем (чаще всего при нажатии клавиш Ctrl+C);GeneratorExit
— вызывается методом close объекта generator;Exception
— исключения, которые можно и нужно обрабатывать (предыдущие были системными и их трогать не рекомендуется).
От Exception наследуются:
StopIteration
— вызывается функцией next в том случае если в итераторе закончились элементы;ArithmeticError
— ошибки, возникающие при вычислении, бывают следующие типы:FloatingPointError
— ошибки при выполнении вычислений с плавающей точкой (встречаются редко);OverflowError
— результат вычислений большой для текущего представления (не появляется при операциях с целыми числами, но может появиться в некоторых других случаях);ZeroDivisionError
— возникает при попытке деления на ноль.
AssertionError
— выражение, используемое в функции assert неверно;AttributeError
— у объекта отсутствует нужный атрибут;BufferError
— операция, для выполнения которой требуется буфер, не выполнена;EOFError
— ошибка чтения из файла;ImportError
— ошибка импортирования модуля;LookupError
— неверный индекс, делится на два типа:IndexError
— индекс выходит за пределы диапазона элементов;KeyError
— индекс отсутствует (для словарей, множеств и подобных объектов);MemoryError
— память переполнена;NameError
— отсутствует переменная с данным именем;
OSError
— исключения, генерируемые операционной системой:ChildProcessError
— ошибки, связанные с выполнением дочернего процесса;ConnectionError
— исключения связанные с подключениями (BrokenPipeError, ConnectionResetError, ConnectionRefusedError, ConnectionAbortedError);FileExistsError
— возникает при попытке создания уже существующего файла или директории;FileNotFoundError
— генерируется при попытке обращения к несуществующему файлу;InterruptedError
— возникает в том случае если системный вызов был прерван внешним сигналом;IsADirectoryError
— программа обращается к файлу, а это директория;NotADirectoryError
— приложение обращается к директории, а это файл;PermissionError
— прав доступа недостаточно для выполнения операции;ProcessLookupError
— процесс, к которому обращается приложение не запущен или отсутствует;TimeoutError
— время ожидания истекло;
ReferenceError
— попытка доступа к объекту с помощью слабой ссылки, когда объект не существует;RuntimeError
— генерируется в случае, когда исключение не может быть классифицировано или не подпадает под любую другую категорию;NotImplementedError
— абстрактные методы класса нуждаются в переопределении;SyntaxError
— ошибка синтаксиса;SystemError
— сигнализирует о внутренне ошибке;TypeError
— операция не может быть выполнена с переменной этого типа;ValueError
— возникает когда в функцию передается объект правильного типа, но имеющий некорректное значение;UnicodeError
— исключение связанное с кодирование текста в unicode, бывает трех видов:UnicodeEncodeError
— ошибка кодирования;UnicodeDecodeError
— ошибка декодирования;UnicodeTranslateError
— ошибка перевода unicode.
Warning
— предупреждение, некритическая ошибка.
Источник: pythonchik.ru