полиморфизм питона - PullRequest
3 голосов
/ 15 июня 2011

Я не могу понять, почему этот код:

class A(object):
    def __init__(self):
        self.__value = 1
    def get_value(self):
        return self.__value

class B(A):
    def __init__(self):
        A.__init__( self )
        self.__value = 2

b = B()

print b.get_value()

дает 1, но не 2. Спасибо за вашу помощь.

Ответы [ 2 ]

7 голосов
/ 15 июня 2011

Ваша проблема в том, что двойные подчеркивания особые в python и создают некоторую частную жизнь (не применяется, но это искажает имена, что и влияет на вас здесь).Вы должны воссоздать это без переменной с двойным подчеркиванием.Кроме того, вы должны использовать super вместо явного вызова A.__init__:

>>> class A(object):
...     def __init__(self):
...             self.value = 1
...     def get_value(self):
...             return self.value
... 
>>> class B(A):
...     def __init__(self):
...             super(B, self).__init__()
...             self.value = 2
... 
>>> b = B()
>>> b.get_value()
2

Для получения дополнительной информации, если вы не хотите читать ссылочную документацию:

Если вы читаетессылка на «специальный» выше, этот параграф описывает внутреннее искажение имени, которое происходит, когда вы используете __.Короткий ответ: A.get_value() возвращает _A__value, а установка self.__value в B фактически устанавливает переменную-член с именем _B__value, что означает, что A.get_value() никогда ее не увидит.

Вы можете доказать это себе, действительно делая что-то действительно хинки:

>>> class A(object):
...     def get_value(self):
...             return self._B__value
... 
>>> class B(A):
...     def __init__(self):
...             self.__value = 2
... 
>>> b = B()
>>> b.get_value()
2
3 голосов
/ 15 июня 2011

self.__value = 1 создает «приватное» поле, которое таким образом невидимо для детей.

Используйте одно подчеркивание для «защищенных» полей.

Например, self._value = 1

Когда вы создаете поле с именем, начинающимся с двойного подчеркивания, Python вносит некоторые изменения в него перед добавлением к объекту __dict__:

>>> class A(object):
...     def __init__(self):
...         self.__value = 1
...     def get_value(self):
...         return self.__value
...
>>> A().__dict__
{'_A__value': 1}

Именно поэтому поле __value не видно в дочернем объекте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...