2

有这个代码:

class A:
  __x = 2

  def f(self):
    print(dir(self)) # there is attribute _A__x, but not __x
    print(self.__x) # prints 2
    print(self._A__x) # prints 2

x = A()
x.f()
print(x.__x) # AttributeError: 'A' object has no attribute '__x'

为什么在方法内部允许访问__x变量,self.__x但不允许在此方法外部访问?我知道带有两个下划线的名称被损坏了,但问题是有什么特别之处,因此这个未损坏的版本在方法中起作用,尽管self只有损坏的版本作为属性。

编辑:

我注意到,如果将某些属性添加到具有表单名称的类中_A__name,例如:

class A:
  _A__y = 3

  def f(self):
    print(self.__y) # prints 3
    print(self._A__y) # prints 3

x = A()
x.f()

然后在类内部,例如,当解释器查找变量时,__y他也可以使用_A__y名称,因此前缀的_A工作原理类似于 C++ 中的范围解析,例如A::. 但我不确定它是如何工作的细节。

所以可以扩展原始问题,为什么在这种情况下self.__y具有与定义相同的self._A__y效果_A__y

4

2 回答 2

4

以两个前导下划线命名的属性是“隐藏的”,以便在类之外使用(见下文)。这与其他语言中的私有属性类似。

重要的是,您不能从类外部访问属性,x.__x可以使用x._A__x. 在类内部,您可以两种方式使用(如示例中所示)。

在 C++ 等其他语言中,您可以将其声明__x为私有,并且您可以在类内部__x和外部使用它,而您不能。在 python 中它是相似的,因为你在内部也使用它,在__x外部你不应该使用它。

在此处查找有关此行为的文档。

于 2013-05-25T12:06:11.917 回答
1

self.__x将被破坏并变成self._A__x,这就是它起作用的原因。修改仅在类定义内的代码中完成。

于 2013-05-25T12:08:30.103 回答