Python单引号和双下划线变量的问题

时间:2013-04-01 05:26:47

标签: python inheritance

我不确定我做错了什么;或者为什么会这样。

我有以下代码:

class Expression (Node):
  """
  ...
  """

  def __init__ (self):
    self.__expressionType = None


  def expressionType (self):
    return self.__expressionType


class Number (Expression):
  """
  Number .
  """

  def __init__ (self, value):
    """
    Value is an entry of type Constant.
    """
    Expression.__init__(self)
    assert isinstance (value, KST.Constant)
    self.__constant = value
    self.__expressionType = value.elementType()

对于一个数字对象说n = Number(KST.Constant(..)),对于以下语句,我总是返回None -

 n.expressionType()

现在,如果我将双下划线更改为单个下划线,则一切正常。我理解私有和半私有变量之间的区别,但为什么会这样 - 我不知道。此外,我在其他许多地方都使用过“__”,这一切似乎都很好。

3 个答案:

答案 0 :(得分:6)

带有双下划线的属性名称为“mangled”,以便在子类中更难使用冲突的名称。

因此请使用单个下划线。

答案 1 :(得分:0)

这是因为name mangling正在发生。

  • expressionTypeExpression
  • 中定义
  • n.__expressionType将翻译为n._Expression__expressionType
  • 如果您将相同的expressionType方法复制粘贴到类Number,那么由于方法解析顺序,它将会出现在Number {{1}中的定义意思是self.__expressionType

self._Number__expressionType!= n._Expression__expressionType

这实际上有效:

n._Number__expressionType

但是,存在代码重复,因此使用单个下划线更好,因为它不会破坏属性的名称。

答案 2 :(得分:0)

正如其他人所指出的," namemangling"发生。但到底是什么意思呢?让我们看一个例子。

创建A:

的实例
class A():
  var1=10
  __var2=20

a=A()

访问A的第一个变量:

>>> a.var1
10

访问A:

的第二个变量
>>> a.__var2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: A instance has no attribute '__var2'

请注意错误A instance has no attribute '__var2'。但是你可以通过以下方式访问它:

>>> a._A__var2
20

简单地说,只要你在方法或变量前面有两个双核(或更多),Python就会通过附加下划线类名来更改该方法或变量的名称到它。这是一种伎俩,所以程序员不会通过错误地改变价值来搞砸事情。