在函数内访问受损的名称可以工作,但外部函数不能

时间:2013-05-25 12:00:55

标签: python

有这段代码:

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.__yself._A__y具有相同的效果,仅定义了_A__y

2 个答案:

答案 0 :(得分:4)

以两个前导下划线命名的属性被“隐藏”以供在类之外使用(实际上未在下面看到)。它与其他语言中的私有属性类似。

重要的是,无法使用x.__x从课堂外访问该属性,但可以使用{{1}访问该属性}。在课程内部,您可以使用(如示例中所示)两种方式。

在其他语言(如C ++)中,您会将x._A__x声明为私有,而您可以在课程中将其用作__x,而在外部则不能。{在python中它是类似的,因为你在里面也使用__x,在外面你不应该使用它。

查看here以获取此行为的文档。

答案 1 :(得分:1)

self.__x将被修改并转入self._A__x,这就是它的原因。 Mangling只在类定义中的代码中完成。