我编写了一个元类,它统计每个子类的实例数。
所以我的meta有一个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"
它工作得很好,但我想增加一个信息隐藏级别。也就是说,元类是元计数器的类不应该具有具有相同元计数器的其他类的实例计数器。他们应该只知道有关其实例数量的信息。
因此MetaCounter._counter
应该显示整个dict,但是Foo._counter
(让Foo是一个类,其元类使用元计数器)应该只返回Foo实例的数量
有没有办法做到这一点
我试图重写__getattribute__
,但结果是弄乱了计数逻辑
我还尝试将_counter
作为属性放在__new__
方法的dict
参数中,但后来它也变成了实例成员,我不想这样做
我不知道足够的元类来说明做你正在尝试的事情是否是个坏主意,但这是可能的
您可以使
MetaCounter
只保留对其“元类化”类的引用,并通过更新MetaCounter.__new__
方法中的dict
为每个类添加特定的实例计数器:每次实例化一个新的
MetaCounter
类时,都会递增计数器这确保了每个
MetaCounter
类都拥有自己的实例计数器,而不知道其他MetaCounter
类的任何信息然后,要获取所有计数器,可以将
_counters
静态方法添加到MetaCounter
,该方法返回每个MetaCounter
类的计数器:那么你就完成了:
这是一个工作示例,使用描述符来修改
_counter
属性的行为,基于它是由实例(类)访问还是由类(本例中的元类)访问相关问题 更多 >
编程相关推荐