Как сделать переопределение атрибута класса обязательным

У меня есть класс BaseWeapon как сделать так, чтобы после наследования его другим классом обязательно нужно было переопределять атрибут self.stats? Предполагаю, что нужно использовать модуль abc из стандартной библиотеки. Класс BaseWeapon:

class BaseWeapon:
CLASS = 'weapon'

class Stats:
    def __init__(self, power):
        self.power = power

def __init__(self, owner, name):
    self._owner = owner
    self._name = name
    self._stats = None

@property
def stats(self):
    return self._stats

@stats.setter
def stats(self, another_stats):
    if isinstance(another_stats, self.Stats):
        self._stats = another_stats
    else:
        raise TypeError(f'Value must be Stats class, not {type(another_stats).__name__}')

Примеры ожидаемых подклассов:

class NoWeapon(BaseWeapon):
def __init__(self, owner):
    super().__init__(owner, 'Empty')
    self.stats = self.Stats(power=1)

class Claws(BaseWeapon):
def __init__(self, owner):
    super().__init__(owner, 'Claws')
    self.stats = self.Stats(power=10)

Ответы (1 шт):

Автор решения: Евгений

Вы можете вовсе не объявлять _stats в родительском классе, но всё также обращаться к нему в методах этого класса.
Результатом такого решения будет то, что при попытке вызвать любой метод класса будет вызван AttributeError, если _stats не был определён в классе-наследнике.
Фактически это указывает на то, что _stats нужен, но его ещё нет, потому его нужно определить.

Не забывайте указывать это в документации либо описании класса.

class BaseWeapon:
  """
  Дочерний класс обязан определить атрибут _stats
  """
  CLASS = 'weapon'

  class Stats:
      def __init__(self, power):
          self.power = power

  def __init__(self, owner, name):
      self._owner = owner
      self._name = name
      # self._stats = None - убрать

  @property
  def stats(self):
      return self._stats

  @stats.setter
  def stats(self, another_stats):
      if isinstance(another_stats, self.Stats):
          self._stats = another_stats
      else:
          raise TypeError(f'Value must be Stats class, not 
 {type(another_stats).__name__}')
→ Ссылка