1

我对 Python 中的 @property 和 @value.setter 属性有些困惑。我研究了以下网站,我想我理解了基本概念。

https://www.programiz.com/python-programming/property

经过研究,我制作了以下示例程序,它运行良好。但是在以下情况下,即使我删除了@property 和@value.setter,它仍然可以正常工作。那么,当我们在上面两个方法中添加@property 和@value.setter 时,可能有什么不同呢?

#!/usr/bin/python

class TreeNode(object):
    def __init__(self):
        self._value = None
        self._left_node = None
        self._right_node = None

    @property
    def value(self):
        return self._value

   @value.setter
    def value(self, value):
        self._value = value

def main():
    tree_node = TreeNode()
    tree_node.value = 3 

    print (tree_node.value)


if __name__ == '__main__':
    main()
4

2 回答 2

4

当您不使用@propertyand@value.setter时,tree_node.value = 3只需替换value您之前定义为函数的属性。由于您的属性只是隐藏了真正的变量,因此这两段代码没有任何明显的区别。@property如果该功能实际上正在做一些工作,那将会改变。

例如,您可能希望自动将设置值更改为大于给定值的最小偶数:

class TreeNode(object):
    def __init__(self):
        self._value = None
        self._left_node = None
        self._right_node = None

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        if value % 2 == 1:
            self._value = value + 1
        else:
            self._value = value

def main():
    tree_node = TreeNode()
    tree_node.value = 3

    print (tree_node.value)


if __name__ == '__main__':
    main()

或者,也许您想要两个始终相互关联的不同属性。

class TreeNode(object):
    def __init__(self):
        self._value = 0
        self._left_node = None
        self._right_node = None

    @property
    def value(self):
        return self._value

    @property
    def value2(self):
        return self._value * 2

    @value2.setter
    def value2(self, value):
        self._value = value // 2

    @value.setter
    def value(self, value):
        self._value = value

def main():
    tree_node = TreeNode()
    tree_node.value = 3

    print (tree_node.value)
    print (tree_node.value2)


if __name__ == '__main__':
    main()

这两个 setter 函数将确保值始终保持同步。在上述任何示例中删除装饰器都会破坏它们的功能。

@property和装饰器的目标是在@value.setter每次访问或设置值时允许特殊语义,同时保持常规属性的优雅。

于 2018-12-02T07:37:11.627 回答
1

不同之处在于,如果您删除 @property,则不能执行以下操作(好吧,您可以,但它会引用函数,而不是返回值):

print(tree_node.value)

因为 value 将是一个常规方法,必须像这样调用:

print(tree_node.value())
于 2018-12-02T07:28:10.440 回答