class MyCustomException(Exception):
          pass
      def some_function(value):
          if value < 0:
              raise MyCustomException("Значение должно быть положительным.")
    
  
В Python для создания исключений для различных ситуаций в приложении можно использовать следующие подходы:
ValueError, TypeError, IOError, IndexError, KeyError и многие другие.  Если один из этих исключений подходит для описания возникшей ситуации, его можно просто вызвать:
      
def validate_age(age):
    if not isinstance(age, int):
        raise TypeError("Возраст должен быть целым числом")
    if age < 0:
        raise ValueError("Возраст не может быть отрицательным")
    return age
      Exception или от одного из его подклассов (например, ValueError, если ваше исключение связано с некорректным значением).
      
class CustomError(Exception):
    """Базовый класс для пользовательских исключений."""
    pass
class InsufficientFundsError(CustomError):
    """Вызывается, когда на счете недостаточно средств."""
    def __init__(self, balance, amount_to_withdraw):
        self.balance = balance
        self.amount_to_withdraw = amount_to_withdraw
        self.message = f"Недостаточно средств на счете. Баланс: {balance}, попытка снять: {amount_to_withdraw}"
        super().__init__(self.message)
def withdraw_money(balance, amount):
    if amount > balance:
        raise InsufficientFundsError(balance, amount)
    return balance - amount
      Exception, мы создаем базовое исключение, от которого потом могут наследоваться более специфичные.__init__ метод для инициализации исключения и передачи дополнительной информации (например, сообщения об ошибке, значений переменных).super().__init__(self.message) вызывает конструктор базового класса Exception и передает ему сообщение об ошибке.with) могут быть использованы для обработки исключений в определенных блоках кода и выполнения очистки ресурсов, даже если исключение было вызвано.
      
class FileHandler:
    def __init__(self, filename, mode='r'):
        self.filename = filename
        self.mode = mode
        self.file = None
    def __enter__(self):
        try:
            self.file = open(self.filename, self.mode)
            return self.file
        except FileNotFoundError:
            raise FileNotFoundError(f"Файл {self.filename} не найден.")
    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file:
            self.file.close()
        # Обработка исключения.  Возвращаем True, чтобы подавить исключение.
        # Возвращаем False (или ничего), чтобы исключение было переброшено.
        return False
try:
    with FileHandler('my_file.txt', 'r') as f:
        content = f.read()
        print(content)
except FileNotFoundError as e:
    print(f"Ошибка: {e}")
      try...except позволяют перехватывать исключения и выполнять код для их обработки (логирование, повторная попытка, завершение программы с сообщением об ошибке и т.д.).  Можно перехватывать несколько типов исключений в одном блоке except, а также использовать блок finally для выполнения кода, который должен быть выполнен в любом случае (например, закрытие файла или освобождение ресурсов).
      
try:
    result = 10 / 0
except ZeroDivisionError:
    print("Деление на ноль!")
except TypeError:
    print("Неверный тип данных!")
except Exception as e:
    print(f"Произошла ошибка: {e}") # Ловим все остальные исключения
finally:
    print("Этот блок выполнится всегда")
      logging для записи информации об исключениях в файлы или другие хранилища.  В логи можно записывать тип исключения, сообщение об ошибке, стек вызовов и другую полезную информацию.
       
import logging
logging.basicConfig(filename='app.log', level=logging.ERROR,
                    format='%(asctime)s - %(levelname)s - %(message)s')
try:
    # Код, который может вызвать исключение
    value = int("abc")
except ValueError as e:
    logging.error(f"Произошла ошибка ValueError: {e}", exc_info=True) # Добавляем exc_info=True для захвата стека вызовов
       При разработке исключений важно учитывать следующие моменты: