与属性混淆

时间:2012-10-17 16:48:46

标签: python properties

我是使用属性的新手,所以我将一个简单的测试放在一起,如下所示。在我的测试中,我创建了两个类“Test1”和“Test2”,其中每个类都意味着保存一个值。我试图使用属性来管理对伪隐藏“val”属性的访问。此当前测试不限制“val”属性的任何输入或输出,因为此程序仅用作概念证明。下面显示的两个测试类产生相同的结果,并且应该表示构造属性的不同方法。我所指的属性的示例用法可以在python docs here找到。

根据documentation

  

如果c是C的实例,c.x将调用getter,c.x = value将调用setter,del c.x将删除。

其中C是他们的测试类。我认为通过设置值我的方式将改变_val并将val作为属性。但是在我看来,我访问属性setter的方法实际上是用整数5替换属性,除非我弄错了。我希望有人能澄清我的困惑。

class Test1:
    def __init__(self):
        self._val = 0

    def setVal(self,newVal):
        self._val = newVal
    val = property(lambda self: self._val, setVal, None, "Property for value")

    def __str__(self):
        return "Value: {}".format(self.val)

class Test2:
    def __init__(self):
        self._val = 0

    @property
    def val(self):
        return self._val

    @val.setter
    def setVal(self,newVal):
        self._val = newVal

    def __str__(self):
        return "Value: {}".format(self.val)

def verify(a):
    print("\nCheck with {}".format(a.__class__.__name__))
    print("Value check:",a.val)
    a.val = 5
    print("Value after a.val = 5 is:",a.val)
    print("The actual value is:",a._val)

def main():
    verify(Test1())
    verify(Test2())

if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:4)

来自documentation

  

property([fget[, fset[, fdel[, doc]]]])

     

返回新样式类的属性属性(从对象派生的类)。

仅为新样式对象或类调用描述符。你使用旧式的课程。从基类型object继承:

class Test1(object):
    # your code

class Test2(object):
    def __init__(self):
        self._val = 0

    @property
    def val(self):
        return self._val

    @val.setter
    def val(self,newVal): # should be named as property
        self._val = newVal

    def __str__(self):
        return "Value: {}".format(self.val)

这项工作很好:

>>> verify(Test1())

Check with Test1
('Value check:', 0)
('Value after a.val = 5 is:', 5)
('The actual value is:', 5)

详细了解difference between new-style classes and classic classes