Проблема с вашим кодом заключается в том, что вы неправильно поняли значение name mangling
, это именно то, что вы делаете, добавляя двойной начальный балл в имя переменной.
При настройкепеременная как self.__x
, то, что вы на самом деле делаете, говорит миру за пределами вашего класса, что доступ к нему возможен только при работе внутри класса Outer
.Если вы попытаетесь получить доступ извне, скажем, добавьте после определения obj
следующего print(obj.__x)
, вы увидите ту же проблему.
Манглинг имен означает, что при доступе к переменной вне области вашего класса вы должны вызывать переменную _ClassName__variableName
, поэтому в нашем примере вы должны использовать print(obj._Outer__x)
, чтобы иметь возможность print
переменная.
Поскольку ваш класс Inner
работает так же, как и внешняя область, простейшим решением было бы переписать ваш метод display
следующим образом:
def display(self):
print("str_in : ", self.__str_in)
print("Inside display() of Inner Class")
print("x : ", self.outer._Outer__x)
print("str : ", self.outer._Outer__str)
self.outer.fn()
Теперь другая вещьЯ заметил, и может вызвать проблемы, если вы не сделали этого сознательно, это вызов self.i1 = self.Inner(Outer())
.Здесь вы не используете те же данные объекта, которые вы создали, как obj
, но создаете новый экземпляр Outer
и отправляете его на Inner
.
И в чем проблема с этим? Допустим, вы добавили следующие строки:
obj = Outer()
obj._Outer__x = 10
obj.show()
Тогда результат вашего show()
всегда будет x: 20
, потому что это изменение вы сделали в переменной,был создан для экземпляра, который не был передан Inner
.
Если это не то поведение, к которому вы стремились, просто измените эту строку на:
self.i1 = self.Inner(self)
Так что теперь выэффективно передать экземпляр объекта Inner