如何从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'
有人可以帮忙吗?提前致谢 .
2 回答
您的代码的问题在于您没有正确理解
name mangling
的含义,'s exactly what you'在您的变量名称中添加双重领先分数时正在执行此操作 .将变量设置为
self.__x
时,您实际所做的就是告诉您 class 以外的世界,只有在Outer
类内部操作时才能以这种方式访问它 . 如果你试图访问外部,让我们说obj
定义后添加以下print(obj.__x)
,你会看到同样的问题 .名称修改意味着当访问类的范围之外的变量时,应该调用变量
_ClassName__variableName
,因此,在我们的示例中,您应该使用print(obj._Outer__x)
来能够print
变量 .由于
Inner
类的工作方式相同,因此作为外部范围,最简单的解决方案是以这种方式重写display
方法:现在,我注意到的其他事情,如果你没有有意识地这样做就会产生问题,就是调用
self.i1 = self.Inner(Outer())
. 在这里,您没有使用实例化为obj
的相同对象数据,而是创建Outer
的新实例并将其发送到Inner
.And what's the problem with this? 假设你添加了以下几行:
然后
show()
的输出将始终为x: 20
,因为您在变量中完成的更改是针对未传递给Inner
的实例 .如果这不是您的目标,只需将此行更改为:
所以现在你有效地将实例化的对象传递给
Inner
问题是您在
self.i1 = self.Inner(Outer)
中传递 the class 而不是 an instance ,而self.__str
是 instance 属性 .还有另一个问题 . 您正在使用
__
前缀,该前缀受name mangling影响,因此请尽量避免这种情况 .你有2种方法来解决这个问题:
self.i1 = self.Inner(self)
要么
_str
成为一个类属性: