2013-04-03 8 views
19
class human(object): 
    def __init__(self, name=''): 
     self.name = name 

    @property 
    def name(self): 
     return self._name 

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

class superhuman(human): 
    @property 
    def name(self): 
     return 'super ' + name 

s = superhuman('john') 
print s.name 

# Doesn't work :("AttributeError: can't set attribute" 
s.name = 'jack' 
print s.name 

プロパティをオーバーライドできますが、スーパークラスのセッターを使用できるようにするには、子クラスのセッターをオーバーライドする必要はありません。Pythonはセッターのないゲッターをオーバーライドします

それはpythonicaly可能ですか?

答えて

33

使用元のプロパティのちょうど.getterデコレータ:あなたが親クラス上の元のプロパティ記述子に到達するために完全な名前を使用する必要が

class superhuman(human): 
    @human.name.getter 
    def name(self): 
     return 'super ' + self._name 

注意。

デモンストレーション:

>>> class superhuman(human): 
...  @human.name.getter 
...  def name(self): 
...   return 'super ' + self._name 
... 
>>> s = superhuman('john') 
>>> print s.name 
super john 
>>> s.name = 'jack' 
>>> print s.name 
super jack 

propertyディスクリプタオブジェクトは、それに関連する複数のメソッド(ゲッター、セッターとデリータ)を有することができるにもかかわらず、わずかの目的です。既存のproperty記述子によって提供される.getter,.setterおよび.deleterデコレータ関数は、その1つの特定のメソッドを置き換えて、記述子自体のコピーを返します。

だからあなたhumanベースクラスで何が起こるかは、あなた最初はゲッターと構文でセッターの両方を持っているものとその記述子を置き換え、その後、@propertyデコレータで記述子を作成することです。それはPythonデコレータが元の装飾された関数を同じ名前で置き換えるために機能します。基本的にname = name.setter(name)を実行します。すべての機能の詳細については、How does the @property decorator work?を参照してください。

サブクラスでは、ゲッターだけを置き換えてディスクリプタの新しいコピーを作成するだけです。

関連する問題