Иногда возникает необходимость вручную сгенерировать то или иное исключение. Для этого применяется оператор raise. Например, сгенерируем исключение
try:
age = int(input("Введите возраст: "))
if age > 110 or age < 1:
raise Exception("Некорректный возраст")
print("Ваш возраст:", age)
except ValueError:
print("Введены некорректные данные")
except Exception as e:
print(e)
print("Завершение программы")
Оператору raise передается объект BaseException - в данном случае объект Exception. В конструктор этого типа можно ему передать сообщение, которое затем можно вывести пользователю. В итоге, если age будет больше 110 или меньше 1, то сработает оператор raise, который сгенерирует исключение. В итоге управление программой перейдет к блоку except, который обрабатывает исключения типа Exception:
Введите возраст: 100500 Некорректный возраст Завершение программы
В языке Python мы не ограничены только встроенными типами исключений и можем, применяя наследование, при необходимости создавать свои типы исключений. Например, возьмем следующий класс Person:
class Person:
def __init__(self, name, age):
self.__name = name # устанавливаем имя
self.__age = age # устанавливаем возраст
def display_info(self):
print(f"Имя: {self.__name} Возраст: {self.__age}")
Здесь класс Person в конструкторе получает значения для имени и возраста и присваивает их приватным переменным name и age. Однако при создании объекта Person мы можем передать в конструктор некорректное с точки зрения логики значение - например, отрицательное число. Одним из способов решения данной ситуации представляет генерация исключения при передаче некорректных значений.
Итак, определим следующий код программы:
class PersonAgeException(Exception):
def __init__(self, age, minage, maxage):
self.age = age
self.minage = minage
self.maxage = maxage
def __str__(self):
return f"Недопустимое значение: {self.age}. " \
f"Возраст должен быть в диапазоне от {self.minage} до {self.maxage}"
class Person:
def __init__(self, name, age):
self.__name = name # устанавливаем имя
minage, maxage = 1, 110
if minage < age < maxage: # устанавливаем возраст, если передано корректное значение
self.__age = age
else: # иначе генерируем исключение
raise PersonAgeException(age, minage, maxage)
def display_info(self):
print(f"Имя: {self.__name} Возраст: {self.__age}")
try:
tom = Person("Tom", 37)
tom.display_info() # Имя: Tom Возраст: 37
bob = Person("Bob", -23)
bob.display_info()
except PersonAgeException as e:
print(e) # Недопустимое значение: -23. Возраст должен быть в диапазоне от 1 до 110
В начале здесь определен класс PersonAgeException, который наследуется от класса Exception. Как правило, собственные классы исключений наследуются от класса Exception. Класс PersonAgeException предназначен для исключений, связанных с возрастом пользователя.
В конструкторе PersonAgeException получаем три значения - собственное некорректное значение, которое послужило причиной исключения, а также минимальное и максимальное значения возраста.
class PersonAgeException(Exception):
def __init__(self, age, minage, maxage):
self.age = age
self.minage = minage
self.maxage = maxage
def __str__(self):
return f"Недопустимое значение: {self.age}. " \
f"Возраст должен быть в диапазоне от {self.minage} до {self.maxage}"
В функции __str__ определяем текстовое представление класса - по сути сообщение об ошибке.
В конструкторе класса Persoon проверяем переданное для возраста пользователя значение. И если это значение не соответствует определенному диапазону, то генерируем исключение типа PersonAgeException:
raise PersonAgeException(age, minage, maxage)
При применении класса Person нам следует учитывать, что конструктор класса может сгенерировать исключение при передаче некорректного значения. Поэтому создание объектов Person обертывается в конструкцию try..except:
try:
tom = Person("Tom", 37)
tom.display_info() # Имя: Tom Возраст: 37
bob = Person("Bob", -23) # генерируется исключение типа PersonAgeException
bob.display_info()
except PersonAgeException as e:
print(e) # Недопустимое значение: -23. Возраст должен быть в диапазоне от 1 до 110
И если при вызове конструктора Person будет сгенерировано исключение типа PersonAgeException, то управление программой перейдет к блоку except, который обрабатывает исключения типа PersonAgeException в виде вывода информации об исключении на консоль.