Чтобы запретить создание экземпляров базового класса, но позволить создавать экземпляры дочерних классов в Python, можно использовать два основных подхода:
1. Использование `NotImplementedError` в `__init__`:
class BaseClass:
def __init__(self):
if self.__class__ == BaseClass:
raise NotImplementedError("Нельзя создавать экземпляры базового класса.")
class DerivedClass(BaseClass):
def __init__(self):
super().__init__()
# Дополнительная логика инициализации DerivedClass
# Попытка создания экземпляра BaseClass вызовет исключение
# base_object = BaseClass() # Raises NotImplementedError
# А создание экземпляра DerivedClass будет работать
derived_object = DerivedClass()
Этот подход проверяет тип создаваемого объекта. Если это непосредственно `BaseClass`, то вызывается `NotImplementedError`. Важно отметить, что проверка `self.__class__ == BaseClass` работает, даже если у вас множественное наследование. Альтернативой может быть проверка `isinstance(self, BaseClass) and type(self) is BaseClass`, но она немного более verbose.
2. Использование `abc` (Abstract Base Classes):
from abc import ABC, abstractmethod
class BaseClass(ABC):
@abstractmethod
def some_method(self):
pass # Или raise NotImplementedError, если метод должен быть реализован в подклассах
class DerivedClass(BaseClass):
def some_method(self):
return "Реализация метода в DerivedClass"
# Попытка создания экземпляра BaseClass вызовет TypeError
# base_object = BaseClass() # Raises TypeError: Can't instantiate abstract class BaseClass with abstract method some_method
# А создание экземпляра DerivedClass будет работать, если реализованы все абстрактные методы
derived_object = DerivedClass()
print(derived_object.some_method()) # Выведет: Реализация метода в DerivedClass
Модуль `abc` позволяет создавать абстрактные базовые классы. Абстрактный класс нельзя инстанцировать напрямую. Он предназначен только для наследования. Класс считается абстрактным, если у него есть хотя бы один абстрактный метод (метод, помеченный декоратором `@abstractmethod`). Дочерние классы обязаны реализовать все абстрактные методы родительского класса, иначе они тоже будут считаться абстрактными и их нельзя будет инстанцировать.
Какой подход выбрать?
В целом, использование `abc` с абстрактными методами является более надежным и общепринятым способом запретить создание экземпляров базового класса и обеспечить реализацию необходимых методов в дочерних классах, когда это требуется.