Python Имена сеттеров и геттеров - PullRequest
2 голосов
/ 14 февраля 2020

Я пытаюсь понять, как геттеры и сеттеры работают в python со свойствами, но я запутался в соглашении об именах.

Существует ли определенный c стандарт именования для геттера и сеттер? Почему мне нужно установить возвращаемое имя параметра с "_" (подчеркивание)? Если бы я изменил его на «self.color» вместо «self._color», геттер и сеттер больше не работают. Также, если бы я изменил название функции, функция печати больше не выполняется. Любые разъяснения будут с благодарностью, спасибо!

class FavoriteColor:
    def __init__(self, color):
        self.color = color

    @property
    def color(self):
        print('getter method')
        return self._color

    @color.setter
    def color(self, x):
        print('setter method')
        self._color = x

obj1 = FavoriteColor('blue')

Ответы [ 4 ]

2 голосов
/ 14 февраля 2020

Я думаю, что запутанная часть находится в __init__. self.color = color в __init__ фактически вызывает ваш установщик, который создает приватную переменную с именем _color. Сеттер и геттер работают как оболочки этого приватного _color, что позволяет вам делать что-то большее, чем прямой доступ к необработанной переменной.

Я не знаю, является ли это обычной практикой для вызова сеттера в __init__ , но я предпочитаю определять закрытую переменную в __init__ напрямую. Для меня это выглядит более простым

class FavoriteColor:
    def __init__(self, color):
        self._color = color
1 голос
/ 14 февраля 2020

Если вы сделали это:

@color.setter
def color(self, x):
    self.color = x

Тогда этот установщик будет вызывать себя повторно. Нет никакой разницы между obj1.color = 'blue' и self.color = x, они оба делают одно и то же, то есть вызывают установщик def color. Таким образом, с установщиком, вызывающим себя рекурсивно, у вас есть бесконечная рекурсивная l oop, которая в конечном итоге обработает sh вашу программу.

Для этой цели вам нужно на самом деле сохранить значение в некотором другом атрибуте . Использование "_color" для его имени является довольно очевидным решением.

Обратите внимание, что использование такого типа метода set / getter в Python не одобряется, если ваш метод set / getter не ' т делай что угодно. Вы можете удалить их полностью и просто установить self.color = 'blue' для того же эффекта, что и ваша пара сеттер / геттер в настоящее время. Вы должны использовать только сеттеры / геттеры, если они выполняют дополнительную обработку. Так как синтаксис простого атрибута и метода установки / получения одинаков, вы можете даже безопасно перейти к использованию методов установки / получения позже, если вам нужно (в отличие, скажем, от Java, где установка / получение - foo.setBar(...), который не идентичен foo.bar = ... и не может быть прозрачно заменен позже).

0 голосов
/ 14 февраля 2020

Python переменные и функции имеют одно и то же пространство имен. Таким образом, self.color может ссылаться только на метод получения / установки или на сам атрибут. Общепринятым соглашением является добавление подчеркивания к внутреннему имени атрибута, чтобы избежать этого наименования cla sh, которое также условно передает понятие, что это закрытый атрибут.

Это должно уже объяснить ваш другой вопрос. Если у вас есть метод с именем self.color и он содержит код, в котором он заменяет сам значением, то, конечно, вы больше не можете использовать self.color для повторной ссылки на метод.

Давайте посмотрим на это еще раз с еще более простым примером.

>>> class X:
...   def color (self, value):
...     self.color = value

При первом вызове функции - скажем, xinstance.color("red") - она ​​установит color экземпляра в "red". Поэтому вы больше не можете вызывать xinstance.color() снова, потому что теперь это строка, а не функция.

Добавление декоратора @property несколько меняет это, потому что теперь self.color = value вызовет color для вызова сам, что заставляет его называть себя, что заставляет его снова вызывать себя, и т. д. c.

0 голосов
/ 14 февраля 2020

Как и большинство языков программирования, Python имеет соглашение для определения частных переменных класса с подчеркиванием "_", поэтому, называя "_color", мы имеем в виду создание частного атрибута "color".

И для вашего второго вопроса вы должны определить свойство установщика геттера для атрибута, который вы только что определили. В соответствии с правилами декоратора свойства, мы должны определить то же имя методов сеттера геттера, что и у нашего целевого атрибута с @property Decorator.

Надеюсь, это поможет

class FavoriteColor:
     def __init__(self, color): 
          self._color = color

     # a getter funcion
     @property
     def color(self): 
         return self._color 

     # a setter function 
     @color.setter 
     def color(self, value): 
        self._color = value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...