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)
添加回答
舉報