🐛 Типичные ошибки

Ошибка 1. Забыть наследоваться от ABC

from abc import abstractmethod

class Shape:  # Нет ABC!
    @abstractmethod
    def area(self):
        pass

s = Shape()  # Создаётся без ошибки — контракт не работает

Почему возникает: декоратор @abstractmethod помечает метод, но класс остаётся обычным, если не наследоваться от ABC.

✅ Исправление

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

Ошибка 2. Создать объект наследника без реализации метода

class Dog(Animal):
    pass

d = Dog()  # TypeError: Can't instantiate abstract class Dog
           # with abstract method speak

Почему возникает: если дочерний класс не переопределяет абстрактный метод, он сам остаётся абстрактным.

✅ Исправление

class Dog(Animal):
    def speak(self):
        print("Woof!")

Ошибка 3. Наследовать исключение от BaseException

class MyError(BaseException):  # Плохо
    pass

Почему возникает: BaseException предназначен для системных исключений (KeyboardInterrupt, SystemExit). Обычный except: ловит его, что может привести к неожиданному поведению.

✅ Исправление

class MyError(Exception):  # Хорошо
    pass

Ошибка 4. Забыть вызвать super().__init__()

class AccessDeniedError(Exception):
    def __init__(self, age):
        self.age = age
        # Забыли super().__init__(...)

try:
    raise AccessDeniedError(15)
except AccessDeniedError as e:
    print(e)  # Пустая строка!

Почему возникает: сообщение об ошибке хранится в базовом классе Exception. Без вызова super().__init__() строковое представление остаётся пустым.

✅ Исправление

class AccessDeniedError(Exception):
    def __init__(self, age):
        self.age = age
        super().__init__(f"Access denied: age {age} is too low")

Ошибка 5. Пустое тело абстрактного метода без pass

class Shape(ABC):
    @abstractmethod
    def area(self) -> float:
        # Пустой метод без pass — SyntaxError

Почему возникает: в Python метод должен содержать хотя бы одну инструкцию. Используйте pass или ... (ellipsis).

✅ Исправление

class Shape(ABC):
    @abstractmethod
    def area(self) -> float:
        """Return the area of the shape."""
        pass