のーずいだんぷ

主に自分用メモですが、もしかしたら誰かの役に立つかもしれません

Pythonにはプロパティのgetter、setterは不要、それがパイソニック

今日も一日一文法シリーズ、やる。

Pythonのリファレンスや、参考書を読んでこれは知らなかったなとか、うろ覚えだな…というものを個人的に紹介していく。 勉強中の方の役にたてば嬉しい。そんな趣旨ではじめた。 読者になってもらうと一緒に勉強できておすすめ(勧誘)

教材としてしばらく以下の本を使用する。 今回のトピックスでもここから見つけた。

入門 Python 3

入門 Python 3

1. デコレータによる方法

オブジェクト指向言語では、意図しないプロパティの変更による危険性を排除するためにgetter/setterを介してしかその値を操作できないようになっている。 Pythonでもgetter/Setterを作成できる。その場合は以下のようにデコレータを利用して作成する。

class ExampleClass(object):
    def __init__(self):
        self.value = None

    @property
 def value(self):
        return self.value
    
    @value.setter
    def value(self, arg):
        return self.value = arg

2. propertyによる方法

class ExampleClass(object):
    def __init__(self):
        self.value = None

 def get_value(self):
        return self.value
    
    def set_value(self, arg):
        return self.value = arg

    value = property(get_value, set_value)

最後のproperty(<getter>, <setter>)が重要で、これがない場合通常のgetter、setterとして機能する。 この定義の場合次のようにプロパティを操作できる。

>>> ins = ExampleClass()
>>> ins.value = 'test'
>>> ins.value
'test'

3. プロパティを隠す

さっきのコンストラクタでのプロパティ定義で名前の前に2つのアンダースコア(ダンダー)をつける。

>>> class HiddenProperty(object):
...     def __init__(self):
...             self.__value = None

これは実際には機能的に隠れているわけではない。 1、もしくは2で定義したプロパティvalue__valueへ変更して、アクセスできるか試してみるとアクセスに失敗する。 ただし、実際には直接アクセスしにくい名前に変更されている(マングリング)。なのである値にすることで値にアクセスできてしまう。

4. Pythonではgetter/setterは必要ない

3で述べたように直接のアクセスをしにくくするような昨日は存在するが完全に秘匿はされない。 Pythonではプロパティを秘匿せず直接プロパティを編集することを推奨しているようだ。

ins = ExampleClass()
ins.value = test 
ins.value
test

これは職場によっては批判的に捉えられるかもしれない(そのための上記の設定なのかもしれない) 書く職場、組織の方針に従うべきだろう。