实例变量未继承

2024-10-04 07:33:30 发布

您现在位置:Python中文网/ 问答频道 /正文

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.\u items属性。我真的不明白为什么会这样,我可能犯了一个我找不到的愚蠢的错误。提前谢谢!你知道吗


Tags: importselfreturninitdefitemspassitem
2条回答

您遇到了name mangling-将双下划线前缀更改为单下划线,您将能够在_items处获得。你知道吗

当您使用__(双下划线)时,Python通过将成员的名称更改为_{classname}{original_name}来为您提供psuedo私有成员,只要它在原始类中被引用。您仍然可以通过显式引用重命名的字段来获取子类中的成员,但这就像在静态类型语言中进行反射一样。。。这意味着所有其他的选择都失败了。你知道吗

您可能希望为抽象方法提供一个实现:

# 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。你知道吗

__foo属性很神奇。^在Agenda中的{}在幕后神奇地变为self._Agenda__items。^在StackAgenda中{}变成了self._StackAgenda__items幕后。你知道吗

  1. 最佳实践是永远不要使用__foo属性。

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

相关问题 更多 >