创建没有实现setter的属性

时间:2016-08-16 21:06:59

标签: python python-3.x

class Human:
    def __init__(self) -> None:
        self.name = None  # type: str

    def introduce(self):
        print("I'm " + self.name)


class Alice(Human):
    def __init__(self) -> None:
        super().__init__()
        self.name = "Alice"


class Bob(Human):
    def __init__(self, rude: bool) -> None:
        super().__init__()
        self.rude = rude

    @property
    def name(self) -> str:
        return "BOB!" if self.rude else "Bob"


if __name__ == '__main__':
    alice = Alice()
    alice.introduce()
    bob = Bob(rude=True)
    bob.introduce()

在上面的代码中,有一个抽象的Human类(实际上它不是人类,并且有更复杂的方法,与问题无关)。它的大多数实现都会通过简单地为name属性分配字符串来设置其名称(就像Alice)。但是,如果分配了更复杂的逻辑(值取决于解析时的对象状态),则很少有异常,例如Bob

因此,在Bob类中,我为name属性创建了一个自定义getter。但是作为一种效果,不可能创建一个类实例,因为调用超级构造函数会导致以下错误。

AttributeError: can't set attribute

也不可能添加天真的二传手。

@name.setter
def name(self, name: str):
    self.name = name

为什么呢?因为它会导致无限循环。如何解决这个问题?

3 个答案:

答案 0 :(得分:2)

为什么不制作一个虚拟制作者

@name.setter
    def name(self, value):
        pass

执行self.name = None时,它会调用此setter并实际上什么都不做

答案 1 :(得分:1)

如果您确定您的子类将分配name,那么您可以在父构造函数中省略该分配。现在,Human尝试设置为name,当没有setter时。如果您从Human构造函数中删除它,则Human可能如下所示:

class Human:
    def introduce(self):
        print("I'm " + self.name)

答案 2 :(得分:1)

对于班级Bob,我会在这种情况下使用类似的东西:

@name.setter
def name(self, name: str):
    self._name = name

之后,您可以使用内部值在更复杂的getter中执行任何操作。或者我的问题是错的?

执行代码会给出:

I'm Alice I'm BOB!