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
为什么呢?因为它会导致无限循环。如何解决这个问题?
答案 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!