Я экспериментирую с ООП и пытаюсь реализовать наследование некоторых классов со счетчиками количества экземпляров каждого класса и подкласса.
Я хотел бы иметь переменную класса, которая увеличивается в методе класса __init__
, чтобы при создании экземпляра класса счетчик для этого класса и для всех его родительских и родительских классов увеличивался .
Тем не менее, после ряда попыток я пытаюсь добиться этого, изолируя счетчики для каждого подкласса от родительского класса.
Скажем, у меня есть классы "Cls", "SubCls" и "SubSubCls", как показано ниже.
class Cls():
count = 0
def __init__(self):
#general init stuff
self.__class__.count += 1
class SubCls(Cls):
pass
class SubSubCls(SubCls):
pass
Мне бы хотелось следующее поведение:
a = Cls()
SubSubCls.count #returns 0
SubCls.count #returns 0
Cls.count #returns 1
b = SubCls()
SubSubCls.count #returns 0
SubCls.count #returns 1
Cls.count #returns 2
c = SubSubCls()
SubSubCls.count #returns 1
SubCls.count #returns 2
Cls.count #returns 3
Рациональным для этого является то, что если Cls - это что-то вроде 'Entity', SubCls - это 'Physical Entity', а SubSubCls - это 'Tree', и я создаю один экземпляр Tree, у меня теперь есть 1 Tree, 1 Physical Entity, 1 Сущность - даже если они все в одном объекте.
Лучшее, что я до сих пор придумал, это следующее:
class Cls():
count = 0
def __init__(self):
#general init stuff
self.inc_count()
def inc_count(self):
Cls.count += 1
super().inc_count() #removing this avoids AttributeError but means having
# unique methods for inc_count in all SubCls level Classes
class SubCls(Cls):
count = 0
def __init__(self):
super().__init__()
#unique init stuff
def inc_count(self):
SubCls.count += 1
super().inc_count()
class SubSubCls(SubCls):
count = 0
def __init__(self):
super().__init__()
#unique init stuff
def inc_count(self):
SubSubCls.count += 1
super().inc_count()
Это имеет правильное поведение, но я чувствую, что наследство должно быть лучше. Я не хочу определять inc_count()
отдельно для каждого класса, когда они очень похожи - я хочу, чтобы здесь все было масштабируемым.
Я могу видеть случаи с множественным наследованием как осложнение в будущем, но я пока оставлю это в покое.
Я уверен, что смогу обойти super().inc_count()
в определении для Cls
, вызывая AttributeError, либо используя try и исключения, либо определив MetaCls
выше Cls
- так что я не слишком волнуюсь там.
Однако я почти уверен, что не смогу просто заменить Cls.count += 1
, SubCls.count += 1
и SubSubCls.count += 1
в определении inc_count()
на self.__class__.count += 1
или type(self).count += 1
, так как это просто приведите к действию на счетчик «самого низкого» класса экземпляра несколько раз. (т.е. создание экземпляра SubSubCls приведет к увеличению общего количества SubSubCls на 3, а количество его родительских классов останется неизменным).
Чтобы решить эту проблему, существует ли абстрактный способ ссылки на класс, от которого унаследован метод? Так что мой inc_count определен только на верхнем уровне как что-то вроде этого (и унаследовано всеми подклассами).
def inc_count(self):
DirectParentClassDefinedAtRunTime.count += 1
super().inc_count()
Очевидно, что если я собираюсь получить желаемый эффект совершенно неправильно, я буду рад любым указателям. Мой единственный предыдущий набег в ООП был с Flash в возрасте 12 лет - очень давно.