如何在Python 3中从内部类访问外部类成员?
下面是我的代码段。
class Outer:
def __init__(self):
self.__x = 20
self.__str = "Outer Class"
def show(self):
self.i1 = self.Inner(Outer())
self.i1.display()
def fn(self):
print("Hello from fn() of Outer Class")
print("str : ", self.__str)
class Inner:
def __init__(self, outer):
self.__str_in = "Inner Class"
self.outer = outer
def display(self):
print("str_in : ", self.__str_in)
print("Inside display() of Inner Class")
# print("x : ", self.outer.__x)
# print("str : ", self.outer.__str)
# self.outer.fn()
obj = Outer()
obj.show()
如果我执行注释行,则会引发错误消息-
line 23, in display
print("x : ", self.outer.__x)
AttributeError: type object 'Outer' has no attribute '_Inner__x'
有人可以帮忙吗?预先感谢。
答案 0 :(得分:1)
代码的问题是您不正确理解name mangling
的含义,这就是在变量名中添加双前导分数时所做的。
将变量设置为self.__x
时,您实际上是在告诉类外的世界,只有在Outer
类中进行操作时,才可以通过这种方式访问它。如果您尝试在外部访问,可以说在obj
的定义后面加上以下print(obj.__x)
,您将看到相同的问题。
名称处理意味着在访问类范围之外的变量时,应调用变量_ClassName__variableName
,因此,在我们的示例中,应使用print(obj._Outer__x)
来{ {1}}变量。
由于您的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
的实例进行的。 / p>
如果这不是您要针对的行为,请将此行更改为:
Inner
因此,现在您可以有效地将实例化的对象传递给self.i1 = self.Inner(self)
答案 1 :(得分:0)
问题是您在self.i1 = self.Inner(Outer)
中传递了该类而不是实例,并且self.__str
是实例< / strong>属性。
还有另一个问题。您正在使用受name mangling约束的__
前缀,因此请避免使用该前缀。
您有2种解决方法:
self.i1 = self.Inner(self)
或
为_str
设置类属性:
class Outer:
_str = "Outer Class" # NOTE THE SINGLE _
def __init__(self):
self._x = 20 # NOTE THE SINGLE _
...