将property属性替换为普通属性

时间:2018-05-28 13:00:11

标签: python properties

是否可以用正常的'替换对象的属性?属性?

我需要这个,因为当我访问第一个属性时,我希望该属性生成该值。但我后来不再需要这个属性了:

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存在则检查属性,但我想知道是否可以替换属性本身。

1 个答案:

答案 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'}