Почему функции, работающие с членами с ограниченным доступом дочернего класса, требуют перегрузки для корректной работы? Допустим, есть 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)

21 Авг 2019 в 07:01
310 +1
0
Ответы
1

Проблема здесь заключается в том, что в Python имена с двумя подчеркиваниями в начале считаются "магическими" и Python изменяет их имя, добавляя имя класса в начале. Это делается для предотвращения конфликтов имен между классами.

В вашем случае, когда вы определяете __protected в дочернем классе ChildClass, Python не переопределяет переменную __protected в классе BaseClass, а создает новую переменную __ChildClass__protected.

Чтобы это обойти и иметь доступ к перегруженной переменной __protected из дочернего класса, вам придется переопределить методы, которые используют эту переменную. В противном случае, вы будете обращаться к __protected в базовом классе, который сохранит свое первоначальное значение.

Это то, что происходит с вашим кодом. Когда вы вызываете метод printProtected из дочернего класса ChildClass, он все еще обращается к __protected из базового класса BaseClass, поэтому выводится значение 'Protected param'.

Чтобы получить ожидаемый результат, вам нужно переопределить метод printProtected в дочернем классе ChildClass, чтобы он обращался к правильной переменной __protected.

20 Апр 2024 в 13:09
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир