5

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

我有以下代码:

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()

对于一个数字对象 say n = Number(KST.Constant(..)),对于以下语句,我总是返回 None ——</p>

 n.expressionType()

现在,如果我将双下划线更改为单下划线,一切正常。我了解私有变量和半私有变量之间的区别,但为什么会发生这种情况——我不知道。此外,我在其他许多地方都使用了“__”,而且一切似乎都很好。

4

3 回答 3

7

带有双下划线的属性名称是“错位的”,以便在子类中更难出现名称冲突。

所以使用单下划线。

于 2013-04-01T05:31:15.090 回答
1

正如其他人指出的那样,会发生“名称混乱”。简单来说,Python 会更改变量名,使程序员无法通过纯内存访问它们。

例子:

class A():
  var1 = 10    # typical variable
  __var2 = 20  # double-underscored variable

现在您会注意到您无法访问双下划线变量..

>>> A.var1
10
>>> A.__var2
  AttributeError: type object 'A' has no attribute '__var2'

..除非你知道 Python 如何改变你的变量名

>>> a._A__var2
20

这本质上与privateJava 和其他编程语言中的行为相同,您不希望程序员意外更改值。

于 2014-10-01T10:35:31.080 回答
0

这是因为名称修改正在发生。

  • expressionType中定义Expression
  • n.__expressionType将转换为n._Expression__expressionType.
  • 如果您将相同的expressionType方法复制粘贴到类Number中,那么由于方法解析顺序,它将采用出现在Numberwhere 中self.__expressionType的定义self._Number__expressionType

n._Expression__expressionType!= n._Number__expressionType

这实际上会起作用:

class Expression(Node):
  def __init__(self):
    self.__expressionType = None
  def expressionType(self):
    return self.__expressionType

class Number(Expression):
  def __init__ (self, value):
    Expression.__init__(self)
    assert isinstance (value, KST.Constant)
    self.__constant = value
    self.__expressionType = value.elementType()
  def expressionType (self):
    return self.__expressionType

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

于 2013-04-01T05:42:27.810 回答