Я написал метакласс, который подсчитывает количество экземпляров для каждого дочернего класса. Итак, моя мета имеет dict, например {classname: number_of_instances}
.
Это реализация:
class MetaCounter(type):
_counter = {}
def __new__(cls, name, bases, dict):
cls._counter[name] = 0
return super().__new__(cls, name, bases, dict)
def __call__(cls, *args, **kwargs):
cls._counter[cls.__name__] += 1
print(f'Instantiated {cls._counter[cls.__name__]} objects of class {cls}!')
return super().__call__(*args, **kwargs)
class Foo(metaclass=MetaCounter):
pass
class Bar(metaclass=MetaCounter):
pass
x = Foo()
y = Foo()
z = Foo()
a = Bar()
b = Bar()
print(MetaCounter._counter)
# {'Foo': 3, 'Bar': 2} --> OK!
print(Foo._counter)
# {'Foo': 3, 'Bar': 2} --> I'd like it printed just "3"
print(Bar._counter)
# {'Foo': 3, 'Bar': 2} --> I'd like it printed just "2"
Он отлично работает, но я хочу добавить уровень сокрытия информации. То есть классы, для которых metaclass является MetaCounter, не должны иметь счетчик экземпляров других классов с такой же мета. У них должна быть только информация о количестве их экземпляров. Таким образом, MetaCounter._counter
должен отображать весь dict, а Foo._counter
(пусть Foo будет классом с MetaCounter в качестве его метакласса) должен просто возвращать количество экземпляров Foo.
Есть ли способ добиться этого?
Я пытался переопределить __getattribute__
, но это закончилось возни с логикой подсчета.
Я также пытался поместить _counter
в качестве атрибута в параметр dict
метода __new__
, но тогда он также стал членом экземпляра, а я этого не хотел.