Почему функции, работающие с членами с ограниченным доступом дочернего класса, требуют перегрузки для корректной работы? Допустим, есть 2 класса: BaseClass и ChildClass. Если если перегрузить protected переменную в конструкторе дочернего класса, она не обновиться в методах, доставшихся от базового:class BaseClass(object): def __init__(self, param): self.public = param self.another_public = 'Another public param' self.__protected = "Protected param"
def getProtectedParam(self): return self.__protected def printProtected(self): print(self.__protected) def printPublic(self): print(self.public) def printAnother(self): print(self.anotherPublic) class ChildClass(BaseClass): def __init__(self, param, newpub): super().__init__(param) # Переопределяю переменные self.another_public = newpub self.__protected = 'New protected param' def newPrintFunc(self): print(self.__protected) if __name__ == '__main__': base = BaseClass('Public param') base.printPublic() base.printAnother() base.printProtected() print(base.getProtectedParam(), '\n') child = ChildClass("Child public param", "New another public param") child.printPublic() # Public param child.printAnother() # New another public param child.printProtected() # Protected param print(child.getProtectedParam()) # Protected param child.newPrintFunc() # New protected param Если перегрузить метод getProtectedParam, то значение будет возвращено новое:# Теперь printProtected выводит New protected param def printProtected(self): print(self.__protected)
Проблема здесь заключается в том, что в Python имена с двумя подчеркиваниями в начале считаются "магическими" и Python изменяет их имя, добавляя имя класса в начале. Это делается для предотвращения конфликтов имен между классами.
В вашем случае, когда вы определяете __protected в дочернем классе ChildClass, Python не переопределяет переменную __protected в классе BaseClass, а создает новую переменную __ChildClass__protected.
Чтобы это обойти и иметь доступ к перегруженной переменной __protected из дочернего класса, вам придется переопределить методы, которые используют эту переменную. В противном случае, вы будете обращаться к __protected в базовом классе, который сохранит свое первоначальное значение.
Это то, что происходит с вашим кодом. Когда вы вызываете метод printProtected из дочернего класса ChildClass, он все еще обращается к __protected из базового класса BaseClass, поэтому выводится значение 'Protected param'.
Чтобы получить ожидаемый результат, вам нужно переопределить метод printProtected в дочернем классе ChildClass, чтобы он обращался к правильной переменной __protected.
Проблема здесь заключается в том, что в Python имена с двумя подчеркиваниями в начале считаются "магическими" и Python изменяет их имя, добавляя имя класса в начале. Это делается для предотвращения конфликтов имен между классами.
В вашем случае, когда вы определяете __protected в дочернем классе ChildClass, Python не переопределяет переменную __protected в классе BaseClass, а создает новую переменную __ChildClass__protected.
Чтобы это обойти и иметь доступ к перегруженной переменной __protected из дочернего класса, вам придется переопределить методы, которые используют эту переменную. В противном случае, вы будете обращаться к __protected в базовом классе, который сохранит свое первоначальное значение.
Это то, что происходит с вашим кодом. Когда вы вызываете метод printProtected из дочернего класса ChildClass, он все еще обращается к __protected из базового класса BaseClass, поэтому выводится значение 'Protected param'.
Чтобы получить ожидаемый результат, вам нужно переопределить метод printProtected в дочернем классе ChildClass, чтобы он обращался к правильной переменной __protected.