Наследование Python и вызов конструктора родительского класса

Это то, что я пытаюсь сделать в 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'

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

Ответы

Ответ 1

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

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

Итак, ваш атрибут не назван __ test, но _BaseClass__test.

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

Ответ 2

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

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

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

Подробнее о .

Ответ 3

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

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