次の例は、基底クラスFoo
のgetterプロパティx
に派生クラスでsetterを追加する方法です。
class Foo:
def __init__(self):
self._x = "I'm Foo.x"
@property
def x(self):
return self._x
class Bar(Foo):
@Foo.x.setter
def x(self, value):
self._x = value
実行すると、次のようになります。
>>> b = Bar()
>>> b.x
"I'm Foo.x"
>>> b.x = "I'm Bar.x"
>>> b.x
"I'm Bar.x"
さらに、deleterを追加する場合は、次のように書きます。
class Foo:
def __init__(self):
self._x = "I'm Foo.x"
@property
def x(self):
return self._x
class Bar(Foo):
@Foo.x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
self._x = "Nothing"
実行すると下記のようになります。
>>> b = Bar()
>>> b.x
"I'm Foo.x"
>>> b.x = "I'm Bar.x"
>>> b.x
"I'm Bar.x"
>>> del b.x
'Nothing'
最後のデコレータは、@Foo.x.deleter
ではなく、@x.deleter
である点が注意です。
@Foo.x.deleter
とすると、setterが無いプロパティが生成されてしまいます。その理由は以下です。
setterのデコレータにあるFoo.x
は、property
オブジェクトです。Foo.x
は、getterしか持っていません。
property
オブジェクトのsetter
メソッドは、引数の関数をsetterに追加した新たなproperty
オブジェクトを返します。つまり、Bar
の@Foo.x.setter
デコレータで始まる定義で、Bar.x
にはgetterとsetterを持つproperty
オブジェクトが生成されBar.x
に代入されています。
property
オブジェクトの、deleter
メソッドは、引数の関数をdeleterに追加した新たなproperty
オブジェクトを返します。@Foo.x.setter
デコレータで始まる定義で、Bar.x
にはgetterとsetterを持つproperty
オブジェクトが生成され代入されているので、@x.deleter
とすると、getterとsetterに加え、deleterが追加されます。(@Foo.x.deleter
とするとsetterを持たないFoo.x
から新しいプロパティオブジェクトを生成することになるので、@Foo.x.setter
で作成したsetterを持つプロパティオブジェクトを上書きしてしまいます。)
(setterとdeleterの定義の順番が逆の場合、逆に@Foo.x.deleter
と@x.setter
とする必要があります。)
参考