Python @property 会导致 AttributeError ,表示对象没有特定属性。有什么问题吗?

问题描述 投票:0回答:1

我刚刚开始学习 @property 在 Python 中实现 getter 和 setter 方法。我知道为了不让它最终成为 RecursionError,我们必须在本地更改属性名称,例如添加下划线作为前缀。但是当我尝试实现它时,我得到了一个 AttributeError ,它表示对象(子类)缺少我在其超类中更改的特定属性,正如我之前提到的。这是我的代码。

class Handler(ABC):
    @property
    def parent(self) -> Handler:
        return self._parent
    
    @parent.setter
    def parent(self, parent: Handler):
        self._parent = parent

    @abstractmethod
    def handle(self):
        pass

    def add_child(self, child):
        pass

class ThingHandler(Handler):
    def __init__(self, name):
        self.name = name
        self.string = self._make_string()
        self._children: List[Handler] = list()

    def handle(self):
        ... # method implementation, not important atm.
    
    def add_child(self, child: Handler):
        self._children.append(child)
        child.parent = self

    def __str__(self):
        return self.string

    def _make_string(self):
        name = self.name.lower().replace(" ", "_")
        return str(self.parent) + f".{name}"

当我在

ThingHandler
方法中遇到错误(特别是在我调用 self.parent 的最后一行)时,我只是想初始化
_make_string
。错误信息是

AttributeError: 'ThingHandler' object has no attribute '_parent'. Did you mean: 'parent'?

指Handler中的

return self._parent
行。我也在尝试 python 的 ABC,以防它与错误有关。

有什么解决方案/建议吗?

python python-3.x properties
1个回答
0
投票

您没有在类构造函数中初始化

_parent
。 您需要定义初始化
__init__
self._parent
魔术方法。

class Handler(ABC):
    def __init__(self) -> None:
        self._parent = None

    @property
    def parent(self) -> Handler:
        return self._parent
    
    @parent.setter
    def parent(self, parent: Handler):
        self._parent = parent

    @abstractmethod
    def handle(self):
        pass

    def add_child(self, child):
        pass

这将创建

_parent
属性,您将在稍后的代码中引用该属性。

然后你还需要在子类中运行构造函数,因为你覆盖了它。使用

super()
来实现这一点。

class ThingHandler(Handler):
    def __init__(self, name):
        super().__init__()
        self.name = name
        self.string = self._make_string()
        self._children: List[Handler] = list()

这将防止构造函数覆盖。

© www.soinside.com 2019 - 2024. All rights reserved.