【发布时间】:2020-12-28 04:02:25
【问题描述】:
我正在尝试创建一个类,其实例可以具有任意数量的属性。这可以在 init 方法中使用**kwargs 轻松实现。然后,对于它的每个属性,我需要计算实例整个生命周期中的访问次数。
如果我对每个属性都有一个 property,那么我可以在 getter 和 setter 方法中为访问的该属性增加一个计数器给定的时间。
问题是我需要动态创建这些属性,因为我不知道我的类的实例将具有哪些属性。
我相信这可以通过metaclasses 解决。虽然,我正在尝试没有他们来解决这个问题。
到目前为止,我已经编写了这段代码:
class CountAttr:
def __init__(self, **kwargs):
# here I init the counter for each keyword argument
self.__count = {attr: 0 for attr in kwargs}
# then I add the attribute to my instance
for kwarg in kwargs:
object.__setattr__(self, '_' + kwarg, kwargs[kwarg])
def getter(self):
self.__count[kwarg] +=1
return object.__getattribute__(self, '_' + kwarg)
def setter(self, value):
self.__count[kwarg] +=1
object.__setattr__(self, '_' + kwarg, kwargs[kwarg], value)
#here comes the issue: the property doesn't work
object.__setattr__(self, kwarg, property(getter, setter))
@property
def count(self):
return self.__count
test = CountAttr(x=5, y=6)
print(test.x, test.y)
调试我的代码,我评估出test 的属性_x 的值为5,以及属性_y 的值为6。 x 和 y 显示为 property objects,所以一切似乎都正常。但它并没有结束。
确实,最终的打印语句会输出这个:
<property object at 0x7fbb241d4b30> <property object at 0x7fbb241d4b80>
而我期望的输出是:5 6,即_x 和_y 属性的值。
【问题讨论】:
-
问题是
property()的用法和你尝试做的不一样。通常它是 class 中的x = property(getter, setter)直接 而不是方法中的self.x = property(getter, setter)。 -
使用类而不是实例似乎有效:
setattr(CountAttr, kwarg, property(getter, setter))
标签: python python-3.x properties attributes metaclass