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

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

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

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

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

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

20 Апр в 13:09
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 84 028 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир