混淆属性 [英] Confusion with properties

查看:29
本文介绍了混淆属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

根据文档:

<块引用>

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

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

类Test1:def __init__(self):self._val = 0def setVal(self,newVal):self._val = newValval = property(lambda self: self._val, setVal, None, "Property for value")def __str__(self):返回值:{}".format(self.val)类测试2:def __init__(self):self._val = 0@财产定义值(自我):返回 self._val@val.setterdef setVal(self,newVal):self._val = newValdef __str__(self):返回值:{}".format(self.val)定义验证(a):打印("\n检查{}".format(a.__class__.__name__))打印(值检查:",a.val)a.val = 5print("a.val = 5 之后的值是:",a.val)print("实际值为:",a._val)定义主():验证(测试1())验证(测试2())如果 __name__ == '__main__':主要的()

解决方案

来自文档:

<块引用>

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

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

描述符只为新样式对象或类调用.您使用旧式课程.从基本类型 object 继承:

class Test1(object):#你的代码类Test2(对象):def __init__(self):self._val = 0@财产定义值(自我):返回 self._val@val.setterdef val(self,newVal): # 应该被命名为属性self._val = newValdef __str__(self):返回值:{}".format(self.val)

这个工作正常:

<预><代码>>>>验证(测试1())用 Test1 检查('值检查:', 0)('a.val = 5 之后的值是:', 5)('实际值为:', 5)

详细了解新型类和经典类之间的区别.

I am new to using properties, so I put together a simple test as shown below. In my tests, I made two classes "Test1" and "Test2" where each is meant to hold one value. I am attempting to use a property to govern access to the pseudo-hidden "val" attribute. This current test does not restrict any inputs or outputs of the "val" attribute as this program was only meant as a proof of concept. The two test classes shown below yield the same results and are supposed to represent the different methods to construct a property. The example uses for properties I am referring to are found on the python docs here.

As per the documentation:

If then c is an instance of C, c.x will invoke the getter, c.x = value will invoke the setter and del c.x the deleter.

where C is their test class. I thought that by setting the value the way I did would change _val and leave val as a property. However it seems to me that my method of accessing the properties setter is actually replacing the property with the integer 5 unless I am mistaken. I hope someone can clarify my confusion.

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()

解决方案

From documentation:

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

Return a property attribute for new-style classes (classes that derive from object).

Descriptors are only invoked for new style objects or classes. Your using old-style classes. Inherits from a base type 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)

This work fine:

>>> verify(Test1())

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

Read more about difference between new-style classes and classic classes.

这篇关于混淆属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆