实例变量不继承

时间:2014-02-14 18:14:07

标签: python inheritance

import abc

class Agenda(metaclass=abc.ABCMeta):
    def __init__(self):
        self.__items = []

    @abc.abstractclassmethod 
    def addItem(self,item):
        pass

    @abc.abstractclassmethod 
    def getItem (self):
        pass

    def isEmpty(self):
        return self.__items == []

    def clear(self):
        self.__items = []

class StackAgenda(Agenda):
    def __init__(self):
        super().__init__()

    def addItem(self,item):
        self.__items.append(item)

    def getItem(self):
        return self.__items.pop()

当我尝试使用任何StackAgenda方法时,它告诉我StackAgenda对象没有self .__ items属性。我真的不明白为什么会这样,我可能做了一个我找不到的愚蠢错误。提前谢谢!

2 个答案:

答案 0 :(得分:4)

您已遇到name mangling - 将双下划线前缀更改为单个下划线,您就可以获得_items

当您使用__(双下划线)时,Python会通过将成员的名称更改为原始类中引用的_{classname}{original_name}来为您提供伪私有成员。您可以通过明确引用重命名的字段来获取子类中的成员,但这就像在静态类型语言中突破反射一样......这意味着所有其他选项都失败了。

您可能想要做的是为您的抽象方法提供一个实现:

# These are methods, not class methods
@abc.abstractmethod 
def addItem(self, item):
    self.__items.append(item)

@abc.abstractmethod 
def getItem (self):
    return self.__items.pop()

然后,在您的子类中,您只需调用super().getItem()super().addItem(item) ...但在这种情况下,实际上不需要ABC。

答案 1 :(得分:1)

__foo属性是神奇的。 self.__items中的Agenda在幕后神奇地变为self._Agenda__itemsself.__items中的StackAgenda在幕后成为self._StackAgenda__items

  1. 最佳做法是永远不会使用__foo属性。

  2. 即使我们是 想要使用它们的少数疯狂人,但是他们的应用程序,也不是私有属性的应用程序,如果Python有它们(它没有。)