【问题标题】:Confused about the property decorator and its related getter/setter methods对属性装饰器及其相关的 getter/setter 方法感到困惑
【发布时间】:2023-03-10 04:38:01
【问题描述】:

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

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。

发生了什么事?

【问题讨论】:

    标签: python python-2.x


    【解决方案1】:

    问题在于您的 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}
    

    所以解决方法很简单:通过继承object 使foo 成为一个新样式类

    【讨论】:

    • 或者只使用 Python 3,示例按预期工作。
    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 2018-08-15
    • 2017-11-28
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 2020-07-01
    相关资源
    最近更新 更多