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

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

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

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

Рассмотрим пример, показывающий невозможность операции деления на ноль:

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()

Если пользователь введёт число, тогда программа выведет его. А вот если ввести строку, которая не может быть преобразована в целое число, то будет исключение.

Типы исключений

Разные типы исключений генерируют типы исключений. Рассмотрим самые популярные типы исключений:

  1. IOError – генерирует, если невозможно выполнить операцию ввода/вывода.
  2. IndexError – генерируется, если в последовательности не найден элемент с заданным индексом.
  3. KeyError – если в словаре не найден указанный ключ.
  4. NameError – если не найдено имя(переменной или функции).
  5. SyntaxError – если в коде обнаружена синтаксическая ошибка.
  6. TypeError – если стандартная операция применяется к объекту неподходящего типа.
  7. ValueError – если операция или функция принимает аргумент с неподходящим значением.
  8. 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()

Вывод:


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

Блок 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()

Вывод программы:


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

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

Программа “Тесты 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” с законсервированными списками вопросов и правильных ответов.

Файл с вопросами и ответами создан, а теперь продолжим разработку программы “Тесты”. Листинг программы:

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), мы загрузим списки вопросов и ответов, определим количество вопросов.

Если пользователь введёт некорректные значения, тогда обработка исключений будет выводить ошибку и ответ засчитан не будет.

Вывод программы:


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

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

Также наши вопросы можно взломать без труда. Поэтому рекомендуется зашифровать их.

Вы можете изучить методы шифрования и применить к данной программе. В комментариях жду ваших предложений по улучшению нашего кода. Удачи!

 

 
Поделиться в facebook
Facebook
Поделиться в twitter
Twitter
Поделиться в vk
VK
Поделиться в google
Google+
Поделиться в email
Email

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Группа в VK

Помощь проекту

Обнаружили опечатку?

Сообщите нам об этом, выделите текст с ошибкой и нажмите Ctrl+Enter, будем очень признательны!

Свежие статьи

Похожие статьи

Связи между моделями.

Связи между моделями.

В нашем проекте есть одна модель под названием “Объявления”. В этой статье мы создадим новый класс модели “Rubric”, которая будет представлять рубрики объявлений. Допишем в

 
Параметры полей и моделей.

Параметры полей и моделей.

Для того, чтобы наша административная панель Django выглядела более понятна для обычного пользователя необходимо указать правильные названия полей. Наша созданная модель представляется непонятной аббревиатурой “Bbs”,

 
Административный web-сайт Django.

Административный web-сайт Django.

Административный web-сайт предоставляет доступ ко всем моделям, объявленным во всех приложениях, что составляют проект. С помощью данной панели можно просматривать, добавлять, править и удалять записи,

 

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: