2 回答
TA贡献2003条经验 获得超2个赞
我不知道足够的元类来判断做你正在尝试的事情是否是一个坏主意,但这是可能的。
您可以MetaCounter仅保留对其“元类”类的引用,并通过更新dictinMetaCounter.__new__方法为每个类添加特定的实例计数器:
class MetaCounter(type):
_classes = []
def __new__(cls, name, bases, dict):
dict.update(_counter=0)
metaclassed = super().__new__(cls, name, bases, dict)
cls._classes.append(metaclassed)
return metaclassed
每次MetaCounter实例化一个新类时,都会增加计数器
def __call__(cls, *args, **kwargs):
cls._counter += 1
print(f'Instantiated {cls._counter} objects of class {cls}!')
return super().__call__(*args, **kwargs)
这确保每个MetaCounter类拥有其实例计数器并且不知道其他MetaCounter类的任何信息。
然后,要获取所有计数器,您可以_counters向 中添加一个静态方法MetaCounter,该方法返回每个类的计数器MetaCounter:
@classmethod
def _counters(cls):
return {klass: klass._counter for klass in cls._classes}
然后你就完成了:
print(MetaCounter._counters()) # {<class '__main__.Foo'>: 3, <class '__main__.Bar'>: 2}
print(Foo._counter) # 3
print(Bar._counter) # 2
TA贡献1815条经验 获得超6个赞
这是一个工作示例,使用描述符根据属性是由实例(类)_counter访问还是由类(本例中为元类)访问来修改属性的行为
class descr:
def __init__(self):
self.counter = {}
self.previous_counter_value = {}
def __get__(self, instance, cls):
if instance:
return self.counter[instance]
else:
return self.counter
def __set__(self, instance, value):
self.counter[instance] = value
class MetaCounter(type):
_counter = descr()
def __new__(cls, name, bases, dict):
new_class = super().__new__(cls, name, bases, dict)
cls._counter[new_class] = 0
return new_class
def __call__(cls, *args, **kwargs):
cls._counter += 1
print(f'Instantiated {cls._counter} objects of class {cls}!')
return super().__call__(*args, **kwargs)
添加回答
举报