对属性装饰器及其相关的getter / setter方法感到困惑

时间:2016-01-25 12:38:35

标签: python python-2.x

我一直在做一些Python,我意识到Haven实际上对属性装饰器了解很多,所以我尝试了一个简单的例子。这是我使用的代码:

class foo():
    def __init__(self):
        self.__test = 0

    @property
    def test(self):
        return self.__test

    @test.setter
    def test(self, value):
        self.__test = value

    @test.getter
    def test(self):
        self.__test += 1
        return self.__test

然后我开始在交互式shell中玩它:

>>> bar = foo()
>>> bar.test
1
>>> bar.test
2

到目前为止,该对象的行为与我预期的一样。

然后我尝试检查了setter方法

>>> bar.test = 5
>>> bar.test
5
>>> bar.test
5

怪异。由于某种原因,__ test的值没有递增。

>>> bar._foo__test
2

我以为我把__test设为等于5。

发生了什么?

1 个答案:

答案 0 :(得分:3)

问题是你的foo类是旧的样式类,描述符(以及此类属性)仅用于处理新的样式类。

来自doc

  

请注意,仅为新样式对象或类调用描述符(如果类继承自对象或类型,则该类为新样式)

在这种情况下,使用旧样式类设置bar.test = 5会在实例dict中创建一个test属性,该属性会从类dict中隐藏属性:

>>> bar = foo()
>>> foo.__dict__
{'test': <property object at 0x7f302e64c628>, '__module__': '__main__', '__doc__': None, '__init__': <function __init__ at 0x7f302e658b18>}
>>> bar.test   # test property from class dict is used
1
>>> bar.__dict__
{'_foo__test': 1}
>>> bar.test = 5   # sets test on instance
>>> bar.__dict__
{'test': 5, '_foo__test': 1}

所以解决方案很简单:通过继承foo

使object成为新的样式类