Ошибка 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