class InvalidAgeError(ValueError):
def __init__(self, age, message="Возраст должен быть положительным и меньше 150"):
super().__init__(message)
self.age = age
def set_age(age):
if not 0 < age < 150:
raise InvalidAgeError(age)
print("Возраст установлен")
try:
set_age(-5)
except InvalidAgeError as e:
print(f"Ошибка: {e}, введенный возраст: {e.age}")
Да, можно наследовать собственные исключения от других встроенных классов исключений, кроме Exception
. Основная идея в том, что все встроенные исключения, отличные от Exception
, сами наследуются от Exception
напрямую или через другие встроенные исключения. Поэтому любое исключение, которое вы создадите, в конечном итоге будет наследоваться от Exception
, но при этом можно изменить его поведение или семантику, наследуясь от более специфического встроенного исключения.
Наследование от более конкретного встроенного исключения позволяет более точно классифицировать вашу ошибку и, возможно, упростить обработку исключений в других частях кода. Например, если ваше исключение связано с неверным типом данных, имеет смысл наследоваться от TypeError
.
Вот пример:
class NegativeValueError(ValueError):
"""
Исключение, возникающее, когда передано отрицательное значение,
а ожидается положительное. Наследуется от ValueError,
потому что это связано с некорректным значением.
"""
def __init__(self, value, message="Значение не может быть отрицательным"):
self.value = value
self.message = message
super().__init__(self.message) # Вызываем конструктор родительского класса
def process_positive_value(value):
if value < 0:
raise NegativeValueError(value)
return value * 2
try:
result = process_positive_value(-5)
print(f"Результат: {result}")
except NegativeValueError as e:
print(f"Ошибка: {e.message}, значение: {e.value}")
except ValueError as e:
print(f"Другая ошибка ValueError: {e}") # Обработчик для других ошибок ValueError, если они возможны.
В этом примере NegativeValueError
наследуется от ValueError
. При перехвате исключений можно перехватывать либо конкретно NegativeValueError
, либо более общее ValueError
, что даёт большую гибкость.
Другие примеры: вы можете наследовать исключения от IndexError
для проблем с индексацией, от IOError
для проблем с вводом-выводом, от KeyError
если отсутствует ключ в словаре (но обычно лучше просто перехватывать стандартный KeyError
) и т.д.
Важно помнить, что не стоит создавать исключения без веской причины, и использовать их только в исключительных ситуациях (логично!). Лучше избегать использования исключений для простого контроля потока выполнения программы. Также стоит помнить о принципах DRY (Don't Repeat Yourself) и KISS (Keep It Simple, Stupid).