Обработка исключений является мощным механизмом по управлению программой в особых ситуациях. Он позволяет избежать ее аварийного завершения вследствие внезапных и непредвиденных ошибок.
Разработка программы на любом языке довольно часто бывает связана с возникновением различного рода ошибок, препятствующих получению желаемого результата.
Как правило, не все они приводят к моментальному завершению программы: некоторые ошибки можно ликвидировать еще на этапе компиляции, другие же способны оставаться незамеченными достаточно долгое время, а третьи и вовсе не зависят от программиста и возникают лишь в определенных ситуациях.
Рассмотрим пример, показывающий невозможность операции деления на ноль:
Разработка программы на любом языке довольно часто бывает связана с возникновением различного рода ошибок, препятствующих получению желаемого результата.
Как правило, не все они приводят к моментальному завершению программы: некоторые ошибки можно ликвидировать еще на этапе компиляции, другие же способны оставаться незамеченными достаточно долгое время, а третьи и вовсе не зависят от программиста и возникают лишь в определенных ситуациях.
Рассмотрим пример, показывающий невозможность операции деления на ноль:
print(10 / 0)
После попытки запуска будет выведено:
Traceback (most recent call last):
File "index.py", line 1, in
print(10 / 0)
ZeroDivisionError: division by zero
В данном случае отображается файл, а также номер строки кода, где было выброшено исключение ZeroDivisionError.
Конструкция try/except
Данная конструкция используется и в других языках программирования. В операторе try определяется потенциально опасный фрагмент кода — выполнение которого может вызвать исключения.
Затем пишется оператор except, а блок кода, следующий за ним, будет выполнен только, если система сгенерировала исключение.
Пример обработки исключения:
try:
k = int(input("Введите целое число: "))
print("Вы ввели: ", k)
except:
print("Нужно было ввести целое число!!!")
input()
Если пользователь введёт число, тогда программа выведет его. А вот если ввести строку, которая не может быть преобразована в целое число, то будет исключение.
Типы исключений
Разные типы исключений генерируют типы исключений. Рассмотрим самые популярные типы исключений:
- IOError — генерирует, если невозможно выполнить операцию ввода/вывода.
- IndexError — генерируется, если в последовательности не найден элемент с заданным индексом.
- KeyError — если в словаре не найден указанный ключ.
- NameError — если не найдено имя(переменной или функции).
- SyntaxError — если в коде обнаружена синтаксическая ошибка.
- TypeError — если стандартная операция применяется к объекту неподходящего типа.
- ValueError — если операция или функция принимает аргумент с неподходящим значением.
- ZeroDivisionError — если есть деление на 0.
В Python можно обработать несколько исключений. Рассмотрим пример:
try:
a = int(input("Введите целое число: "))
b = int(input("Введите целое число: "))
print("a/b = ", a/b)
except ValueError:
print("Нужно было ввести целое число!!!")
except ZeroDivisionError:
print("На 0 делить нельзя!")
input()
В примере мы добавили исключения при неправильно введённом значении и при деление на 0. Самостоятельно проверьте работоспособность примера.
Передача аргумента исключения
В Python можно передать в программу свое ругательство, то есть сообщение об ошибки, но при этом программа не будет прервана. Это называется передачей аргумента исключения. Поправим наш прошлый пример:
try:
a = int(input("Введите целое число: "))
b = int(input("Введите целое число: "))
print("a/b = ", a/b)
except ValueError:
print("Нужно было ввести целое число!!!")
except ZeroDivisionError as e:
print("На 0 делить нельзя!")
print("Что сказал нам интерпретатор:")
print(e)
input()
Вывод:
Блок else
Оператор try/except также имеет пункт else. Он работает только в том случае, если в вашем коде нет ни единой ошибки. Исправим наш прошлый пример используя else:
try:
k = int(input("Введите целое число: "))
except:
print("Нужно было ввести целое число!!!")
else:
print("Вы ввели: ", k)
input()
В try принято помещать код, который может сгенерировать исключение. В else можно поместить код, который будет выполнен, если все нормально и исключение не было сгенерировано.
Оператор finally
Также у блока except есть еще один необязательный блок finally, который сработает независимо от того, выполнился код с ошибками или без. Пример:
try:
a = int(input("Введите первое число: "))
b = int(input("Введите второе число: "))
print("a/b = ", a/b)
except ValueError:
print("Это не число!")
except ZeroDivisionError:
print("На ноль делить нельзя!")
except:
print("Неожиданная ошибка.")
else:
print("Код выполнился без ошибок")
finally:
print("Я выполняюсь в любом случае!")
input()
Вывод программы:
Используя обработку исключительных, можно защитить программу от взлома, непредвиденного поведения и в будущем получить детальную информацию по логическим ошибкам, содержащимся в ней.
Видео по теме «Обработка исключений»:
Видео по теме «Обработка исключений»:
Программа «Тесты 2.0»
В статье «Условный оператор IF» мы создавали программу «Тесты». В этой статье мы продолжим разрабатывать данную программу.
Сделаем так, чтобы наши вопросы и ответы хранились в списках. Также у нас будет переменная n, содержащая количество вопросов. Мы с легкостью сможем изменять количество вопросов. В нашей новой версии сделаем защиту нашей программы с помощью конструкция try/except.
Программа «Редактор тестов»
Программа «Редактор тестов» будет записывать вопросы и ответы в файл «test.dat» с помощью модуля pickle.
Преимущество такого подхода в том, что тестируемый не сможет открыть Python-файл программы и просмотреть список правильных ответов. Ведь в «test.dat» все данные хранятся в двоичном виде. Рассмотрим листинг программы:
import pickle
questions = ["""
Сколько бит в одном байте
1) 8
2) 6
3) 4
4) 2
""",
"""
Сколько байт в одном килобайте
1) 1000
2) 1024
3) 1048
4) 256
""",
"""
Компания-разработчик Windows
1) Apple
2) Melkosoft
3) Cybersoft
4) Microsoft
""",
"""
Компания-разработчик MacOS
1) Apple
2) Microsoft
3) Fredd
4) google
""",
"""
Символом какой операционной системы является пингвин
1) Linux
2) FreeBSD
3) MacOS
4) Windows
"""]
answers = [1, 2, 4, 1, 1]
datafile = open("test.dat", "wb")
pickle.dump(questions, datafile)
pickle.dump(answers, datafile)
datafile.close()
input("Файл test.dat создан!")
Рекомендуется изучить статью «Файлы. Работа с файлами в Python» для лучшего понимания работы с файлами в Python.
В результате работы программы будет создан файл «test.dat» с законсервированными списками вопросов и правильных ответов.
Файл с вопросами и ответами создан, а теперь продолжим разработку программы «Тесты». Листинг программы:
В результате работы программы будет создан файл «test.dat» с законсервированными списками вопросов и правильных ответов.
Файл с вопросами и ответами создан, а теперь продолжим разработку программы «Тесты». Листинг программы:
import pickle
mark = 0
print("*" * 10, "Тесты 2.0", "*" * 10)
# загружаем списки вопросов и ответов
try:
datafile = open("test.dat", "rb")
except:
print("Ошибка при загрузке вопросов!")
else:
questions = pickle.load(datafile)
answers = pickle.load(datafile)
datafile.close()
n = len(answers) # количество вопросов и ответов
i = 0
for i in range(0, n):
print(questions[i])
try:
a = int(input("Ваш ответ: "))
if a == answers[i]:
mark = mark + 1
print("Правильно!")
else:
print("Неправильно!")
except:
print("Нужно было ввести число. Ответ засчитан как неправильный!")
print("Вы правильно ответили на ", mark, "вопросов из ", n)
input("Нажмите Enter для выхода")
Подробно рассмотрим код, написанной программы. Вопросы у нас выводятся в цикле for. В цикле мы выводим вопрос из списка «questions», далее читаем ответ, если ответ совпадает с правильным (которые хранятся в списке «answers»), то увеличиваем переменную «mark» и выводим сообщение «Правильно!». В противном случае «Неправильно!».
В коде мы используем обработку исключений — вдруг файл «test.dat» будет отсутствовать. Если же все нормально (блок else), мы загрузим списки вопросов и ответов, определим количество вопросов.
Если пользователь введёт некорректные значения, тогда обработка исключений будет выводить ошибку и ответ засчитан не будет.
Вывод программы:
В коде мы используем обработку исключений — вдруг файл «test.dat» будет отсутствовать. Если же все нормально (блок else), мы загрузим списки вопросов и ответов, определим количество вопросов.
Если пользователь введёт некорректные значения, тогда обработка исключений будет выводить ошибку и ответ засчитан не будет.
Вывод программы:
Программа получилась хорошая, но еще требует множества доработок. Чтобы вопросы не шли по порядку надо написать много вопросов и задавать случайным образом. Чем больше вопросов, тем меньше вероятность того, что пользователи будут получать одинаковые вопросы.
Также наши вопросы можно взломать без труда. Поэтому рекомендуется зашифровать их.
Также наши вопросы можно взломать без труда. Поэтому рекомендуется зашифровать их.