Наследование Python и вызов конструктора родительского класса - PullRequest
14 голосов
/ 16 июля 2009

Вот что я пытаюсь сделать в Python:

class BaseClass:
    def __init__(self):
        print 'The base class constructor ran!'
        self.__test = 42

class ChildClass(BaseClass):

    def __init__(self):
        print 'The child class constructor ran!'
        BaseClass.__init__(self)

    def doSomething(self):
        print 'Test is: ', self.__test


test = ChildClass()
test.doSomething()

Что приводит к:

AttributeError: ChildClass instance has no attribute '_ChildClass__test'

Что дает? Почему это не работает, как я ожидаю?

Ответы [ 3 ]

20 голосов
/ 16 июля 2009

Из документации по питону:

Искажение личного имени: когда идентификатор, который встречается в текстовом определении класса , начинается с двух или более символов подчеркивания и не заканчивается двумя или более символами подчеркивания, он считается личным именем этого класса. Частные имена преобразуются в более длинную форму , прежде чем для них будет сгенерирован код. Преобразование вставляет имя класса перед именем , с удаленными начальными подчеркиваниями и одним подчеркиванием, вставленным перед именем класса. Например, идентификатор __ spam , встречающийся в классе с именем Ham , будет преобразован в _Ham__spam . Это преобразование не зависит от синтаксического контекста, в котором используется идентификатор. Если преобразованное имя очень длинное (длиннее 255 символов), может произойти усечение, определяемое реализацией. Если имя класса состоит только из подчеркиваний, преобразование не выполняется.

Таким образом, ваш атрибут не называется __ test , но _BaseClass__test .

Однако вы не должны зависеть от этого, используйте взамен self._test , и большинство разработчиков Python будут знать, что атрибут является внутренней частью класса, а не общедоступным интерфейсом.

5 голосов
/ 17 июля 2009

Вы можете использовать средства самоанализа Python, чтобы получить информацию, которую вы ищете. Простой dir (тест) даст вам

['_BaseClass__test', '__doc__', '__init__', '__module__', 'doSomething']

Обратите внимание на '_BaseClass__test'. Это то, что вы ищете.

Проверьте это для получения дополнительной информации.

3 голосов
/ 16 июля 2009

Переменные с двойным подчеркиванием можно считать «приватными». Они искажены именем класса, в том числе для защиты нескольких базовых классов от переопределения членов друг друга.

Используйте одно подчеркивание, если вы хотите, чтобы другие атрибуты считали ваш атрибут закрытым.

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