简体   繁体   English

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

[英]Confused about the property decorator and its related getter/setter methods

I've been doing some Python, and I realised I Haven't actually know a lot about the property decorator, so I tried making a simple example. 我一直在做一些Python,但我意识到实际上对属性装饰器并不了解很多,所以我尝试制作一个简单的示例。 This is the code I used: 这是我使用的代码:

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

Then I started playing with it in the interactive shell: 然后,我开始在交互式外壳中使用它:

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

So far the object behaved as I expected it to. 到目前为止,该对象的行为符合我的预期。

Then I tried checking out the setter method 然后我尝试检查setter方法

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

Weird. 奇怪的。 For some reason the value of __test wasn't incremented. 由于某种原因,__test的值未增加。

>>> bar._foo__test
2

I thought I had set __test to be equal to 5. 我以为我将__test设置为等于5。

What's going on? 这是怎么回事?

The problem is that your foo class is an old style class, descriptors (and as such properties) are only intended to work with new style classes. 问题在于您的foo类是旧样式类,描述符(以及此类属性)仅旨在与新样式类一起使用。

From the doc : 文档

Note that descriptors are only invoked for new style objects or classes (a class is new style if it inherits from object or type) 请注意,描述符仅针对新样式的对象或类调用(如果类从对象或类型继承,则该类是新样式)

In this case, with an old style class setting bar.test = 5 creates a test attribute in the instance dict, which shadows the property from the class dict: 在这种情况下,使用旧样式类设置bar.test = 5会在实例dict中创建一个test属性,该属性会bar.test = 5该类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}

So the solution is simple: make foo a new style class by inheriting from object 所以解决方案很简单:通过从object继承,使foo为新样式类

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM