Обработка исключений и ошибок
Ошибки являются частью программирования. Они могут случайными (например, допущенные человеком) и ожидаемыми.
В Python ошибки можно разделить в целом на два вида:
- синтаксические ошибки (syntax error) - ошибки допущенные в исходном коде, т.е. был нарушен синтаксис языка (например, пропущен отступ), при которых программа не будет интерпретирована и исполнена;
- ошибки выполнения (runtime error) - ошибки, которые возникают в ходе выполнения программы.
Про второй вид ошибок в основном и пойдет дальнейший материал.
Конструкция try-except
Конструкция try-except
позволяет “поймать” возникающую ошибку в программе. При этом Python продолжает выполнение программой дальше.
Полный синтаксис:
try:
<инструкции>
except <тип исключения>:
<инструкции>
else: # опционально
<инструкции>
finally: # опционально
<инструкции>
Пример:
try:
print(unknown)
except:
print("Вызвано исключение")
Вызвано исключение
В данном примере исключение вызывается в связи с тем, что переменная unknown
не определена.
Множественные исключения
Блоков except
можно определить бесконечно много, если того требует логика программы. Такой подход часто используется, когда заранее известны вызываемые исключения.
Пример с исключением NameError
, которое вызывается при неопределённой переменной:
try:
print(unknown)
except NameError:
print("Переменная unknown не определена")
except:
print("Произошло что-то еще")
Переменная unknown не определена
Также несколько исключений можно определять в одном блоке через запятую, заключая их в круглые скобки:
try:
number = int("not-number")
except (NameError, ValueError) as e:
print(type(e), e)
except:
print("Произошло что-то еще")
<class 'ValueError'> invalid literal for int() with base 10: 'not-number'
Заметка
С помощью ключевого слова
as
можно присвоить переменной значение объекта, который был создан при вызове исключения. В примере выше переменнойe
присваивается экземпляр классаNameError
илиValueError
в зависимости от вызванной ошибки.
Блок else
Блок else
, следующий за try-except
, будет исполнен в том случае, если никаких ошибок не было вызвано:
try:
print("Что-то произошло?")
except:
print("Да, что-то произошло")
else:
print("Нет, все в порядке")
Что-то произошло?
Нет, все в порядке
Блок finally
Блок finally
будет исполнен не в зависимости от того, была вызвана ошибка или нет:
try:
print(unknown)
except NameError:
print("Переменная unknown не определена")
finally:
print("Все ошибки обработаны!")
Переменная unknown не определена
Все ошибки обработаны!
Данный блок может быть крайне полезен, если надо обязательно выполнить какую-либо завершающую операцию, которая не была сделана в части try-except
.
К примеру, мы хотим записать данные в файл, который не доступен для записи:
try:
outfile = open("test.txt", "w")
try:
outfile.write("Важные данные\n")
except:
print("Что-то пошло не так при записи в файл")
finally:
# Закрываем файловый дескриптор
outfile.close()
except:
print("Что-то пошло не так при открытии файла")
Вызов исключения
Для вызова исключений используется ключевое слово raise
. Можно вызвать исключение, если не соблюдены какие-то условия:
word = 5
if type(word) is not str:
raise TypeError("Не строковые значения не допускаются до печати!")
else:
print(word)
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: Не строковые не допускаются до печати!
assert
Ключевое слово assert
позволяет проверять какие-то простые условия в коде. Если эти условия не выполняются, то вызывается ошибка AssertionError
. Также после запятой опционально можно указать сообщение, которые будет выведено при неверном условии:
word = 5
assert type(word) is str, "Значение переменной не является строкой"
print(word)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError: Значение переменной не является строкой