Использование @property и @ value.setter - PullRequest
0 голосов
/ 02 декабря 2018

Я немного запутался в свойствах @property и @ value.setter в Python.Я изучил следующий веб-сайт и думаю, что понимаю основную концепцию.

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

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Когда вы не используете @property и @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()

Обе функции сеттера гарантируют, что значения всегда синхронизированы.Удаление декораторов в любом из приведенных выше примеров нарушит их функциональность.

Цель декораторов @property и @value.setter - предоставить особую семантику каждый раз, когда вы получаете доступ или устанавливаете значение, сохраняя при этом элегантностьобычные атрибуты.

0 голосов
/ 02 декабря 2018

Разница в том, что если вы удалите @property, вы не сможете сделать следующее (ну, вы можете, но это будет ссылка на функцию, а не на возвращаемое значение):

print(tree_node.value)

потому что тогда значение будет обычным методом, который должен быть вызван так:

print(tree_node.value())
...