2016-08-16 6 views
0
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クラスで私はカスタムゲッターを作成しました。ただし、スーパーコンストラクタを呼び出すと、次のエラーが発生するため、クラスインスタンスを作成することはできません。

AttributeError: can't set attribute 

また、ナイーブセッターも追加することはできません。

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

なぜですか?無限ループが発生するためです。その問題を解決するには?

答えて

2

なぜダミーセッターをしない

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

それがこのセッターを呼び出すと、実際には何も

1

サブクラスでnameが割り当てられることが確実であれば、親コンストラクタで代入を省略することができます。現在、Humanは、セッターがないときにnameに設定しようとしています。私はこのケースでは、このようなものを使用していたクラスBobについて

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

を行いませんが確かに、現在の状態では、開発に役立ちます(型ヒントとatt IDEのリブートのヒント)。 –

1

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

その後、あなたは何でもあなたを行うことができますあなたはHumanコンストラクタからそれを削除した場合、その後、Humanは次のようになります。より複雑なゲッターに内部価値を求めています。それとも質問が間違っていたのですか?コードを実行

は与えるだろう:

self.name = Noneが実行されると

I'm Alice I'm BOB!

+0

内部属性はここでは不要ですが、決して使用されません。それでも、それは解決策のように見えます。 –

関連する問題