是否可以用正常的'替换对象的属性?属性?
我需要这个,因为当我访问第一个属性时,我希望该属性生成该值。但我后来不再需要这个属性了:
class A(object):
@property
def x(self):
self.x = "toto" # Replace property, fail because no setter
return self.x
a = A()
print a.x # "toto"
a.x = "tata"
我知道我可以将值存储在第二个属性中,例如_x
,如果_x
存在则检查属性,但我想知道是否可以替换属性本身。
答案 0 :(得分:1)
为了避免缺少setter,您必须直接操作实例__dict__
字典。但是,您无法使用常规property
对象执行所需操作,因为它是data descriptor。属性访问将始终为实例属性提供数据描述符优先级。
您必须创建自定义描述符,而不是定义__set__
或__delete__
方法:
class CachingProperty(object):
def __init__(self, fget):
self.name = fget.__name__
self.fget = fget
def __get__(self, instance, owner):
if instance is None:
return self
value = self.fget(instance)
instance.__dict__[self.name] = value
return value
此描述符还负责直接在实例__dict__
属性中设置值,从而创建实例属性。
使用上述类而不是property
:
class A(object):
@CachingProperty
def x(self):
return "toto"
演示,显示只有一次调用getter方法:
>>> class Demo(object):
... @CachingProperty
... def foo(self):
... print("Calling the foo property")
... return "bar"
...
>>> d = Demo()
>>> d.foo
Calling the foo property
'bar'
>>> d.foo
'bar'
>>> vars(d)
{'foo': 'bar'}