Почему использование 'object.get_attribute()' лучше, чем object.attribute?

Доброго времени суток.
Изоучаю python и программирование в целом.
На одном из курсов на edX дошел до изучения классов и ооп.
Вот часть данного класса:
class Coordinate(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def getX(self):
        # Getter method for a Coordinate object's x coordinate.
        # Getter methods are better practice than just accessing an attribute directly
        return self.x

Собственно интересует второй комментарий. Почему использование метода лучше, чем прямой доступ к атрибуту?
Допусти имеем:
obj = Coordinate(3, 4)
Почему obj.getX() лучше, чем obj.x?
  • Вопрос задан
  • 2441 просмотр
Решения вопроса 2
bobrovskyserg
@bobrovskyserg
Этого требует ООП-религия ;)
class nested(Coordinate):
    def __init__(self, x, y, parent=None):
        super().__init__(x, y)
        self.parent = parent

    def getX(self):
        if self.parent:
            return self.parent.x + self.x
        return self.x
Ответ написан
@egorsmkv
В комментарии ведь написано - лучшая практика в ООП.

Это перешло из других языков программирования, где по возможности лучше все атрибуты делать приватными, то есть доступными лишь в данном классе, а получать их по специальному методу (геттеру).
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
OMarchenko
@OMarchenko
Random Expansion
Макконнелл С. "Совершенный код":
"Предоставление доступа к данным-членам нарушает инкапсуляцию и ограничивает контроль над абстракцией. Как указывает Артур Риэль, класс Point (точка), который предоставляет доступ к данным:
float x;
float y;
float z;
нарушает инкапсуляцию, потому что клиентский код может свободно делать с данными Point что угодно, при этом сам класс может даже не узнать об их изменении (Riel, 1996). В то же время класс Point, включающий члены:
float GetX();
float GetY();
float GetZ();
void SetX( float x );
void SetY( float y );
void SetZ( float z );
поддерживает прекрасную инкапсуляцию. Вы не имеете понятия о том, реализованы ли данные как float x, y и z, хранит ли класс Point эти элементы как double, преобразуя их в float, или же он хранит их на Луне и получает через спутник".
Ответ написан
Комментировать
sumej
@sumej
DevOps
self.x - хм...
pythoner.name/documentation/tutorial/classes/private
В Python не существует "частных" (приватных) переменных экземпляра, т.е. тех, которые не могут быть доступны, кроме как изнутри объекта. Тем не менее есть соглашение, которое поддерживается большей частью кода Python: идентификатор с префиксом нижней черты (например _spam) должны рассматриваться как непубличная часть API (будь то функция, метод или элемент данных). Следует учитывать, детали реализации и предмет могут быть изменены без предварительного уведомления.
Поскольку есть действительные прецеденты для приватных для класса идентификаторов (а именно, чтобы избежать конфликтов имен с именами, определенными подклассами), есть ограниченная поддержка такого механизма, называемого корректировкой имен (name mangling). Любой идентификатор вида __spam (по крайней мере с двумя первыми подчеркиваниями и не более чем одним завершающим) текстуально заменяются на _classname__spam, где имя класса - это текущее имя класса с начальным символом(ами) подчеркивания. Эта корректировка делается безотносительно к синтаксической позиции идентификатора тех пор, пока это происходит в определении класса.
Корректировка имен полезна для того, чтобы позволить подклассам переопределять методы, не нарушая внутриклассовых вызовов методов. Например:
class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable)
 
    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)
 
    __update = update   # private copy of original update() method
 
class MappingSubclass(Mapping):
 
    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы