1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

基底クラスのgetterプロパティに派生クラスでsetterとdeleterを追加する場合の注意点

Last updated at Posted at 2020-05-16

次の例は、基底クラス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とする必要があります。)

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?