Для создания собственного исключения в Python, необходимо создать класс, который наследуется от встроенного класса Exception (или одного из его подклассов, например, ValueError или TypeError, если это более уместно):
class MyCustomError(Exception):
    """Мое собственное исключение."""
    def __init__(self, message):
        self.message = message
        super().__init__(message)
# Пример использования:
try:
    # ... код, который может вызвать исключение
    raise MyCustomError("Что-то пошло не так!")
except MyCustomError as e:
    print(f"Перехвачено исключение: {e}")
  В конструкторе (__init__) обычно инициализируется сообщение об ошибке, которое передается базовому классу Exception.
Для создания собственного исключения в Python, вам нужно создать новый класс, который наследуется от базового класса Exception или одного из его подклассов (например, ValueError, TypeError).  Как правило, достаточно наследоваться непосредственно от Exception.
Вот пример:
class MyCustomException(Exception):
    """
    Это пользовательское исключение.  Можно добавить документацию здесь,
    чтобы объяснить, что оно означает и когда должно быть вызвано.
    """
    def __init__(self, message="Произошла ошибка"):
      """
      Конструктор класса. Можно настроить сообщение об ошибке.
      """
      self.message = message
      super().__init__(self.message)  # Вызов конструктора базового класса
    def __str__(self):
      """
      Строковое представление исключения.  Переопределение позволяет
      контролировать, как исключение будет отображаться при печати.
      """
      return f"MyCustomException: {self.message}"
Объяснение:
class MyCustomException(Exception)::  Это определяет новый класс исключения с именем MyCustomException, который наследуется от Exception."""...""":  Документационная строка (docstring) описывает назначение исключения.  Это хорошая практика для улучшения читаемости кода.def __init__(self, message="Произошла ошибка"):: Это конструктор класса. Он принимает необязательный аргумент message, который используется для хранения описания ошибки.  По умолчанию установлено значение "Произошла ошибка".self.message = message:  Сохраняет сообщение об ошибке в атрибуте экземпляра.super().__init__(self.message):  Вызывает конструктор базового класса Exception, передавая ему сообщение об ошибке.  Это важно, чтобы базовый класс мог правильно инициализировать исключение.def __str__(self)::  Переопределяет метод __str__, который определяет, как исключение будет отображаться в виде строки (например, при печати или логировании).  Это позволяет создать более информативное представление исключения.Пример использования:
def process_data(data):
    if not isinstance(data, list):
      raise MyCustomException("Ожидается список, получен: " + str(type(data)))
    if len(data) == 0:
      raise MyCustomException("Список пуст")
    # Дальнейшая обработка данных
    print("Данные успешно обработаны")
try:
  process_data("not a list")
except MyCustomException as e:
  print(e)  # Выведет: MyCustomException: Ожидается список, получен: <class 'str'>
try:
  process_data([])
except MyCustomException as e:
  print(e) # Выведет: MyCustomException: Список пуст
try:
  process_data([1, 2, 3])
except MyCustomException as e:
  print(e)
else:
  print("Все прошло успешно.")
Важные моменты:
Exception или его подкласса.  Это гарантирует, что ваш класс будет распознан как исключение.__init__:  Используйте конструктор для инициализации любых атрибутов исключения, таких как сообщение об ошибке. Не забудьте вызвать super().__init__(message).raise MyCustomException(...).try...except, как и любое другое исключение.