とりあえずの独り言

テーマは特に限定せず、独り言のように

pythonのsetter/getterを書こうとしただけなのに、地味にはまった件

ひさびさにpythonを書いていて、setter/getter的なやつのpropertyってどうやって書いたっけかな?って 軽くググって流し読みして試したら、なんかエラーが出て地味にはまった

デコレータを付けます的なことしか書いていないのが多かったんで、なんでこうなのかってのは書いてないんで「あれ?」ってなった

最初に書いたやつ
class Hoge:

    @property
    def foo(self):
        return self.foo

    @foo.setter
    def foo(self, foo):
        self.foo = foo


hoge = Hoge()
hoge.foo = 'test'
print(hoge.foo)

エラー内容:

  [Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded

再帰的に繰り返し呼ばれていますよって言われてて、def foo(self, foo) の中で自分自身を読んでしまっていることが原因

とりあえずの解消
class Hoge:

    @property
    def foo(self):
        return self.hidden_foo

    @foo.setter
    def foo(self, foo):
        self.hidden_foo = foo

こうやれば、エラーは出なくなるけど
getter/setter を作った意味がない

f:id:manma_shiro:20200114202358p:plain

※ 属性値が、呼び側で見えてしまっている

こんな感じで修正
class Hoge:

    def __init__(self):
        self.__foo = ''

    @property
    def foo(self):
        return self.__foo

    @foo.setter
    def foo(self, value):
        self.__foo = value

アンダースコアを2こ重ねると、private的な扱いの変数になる(厳密には、違うらしいが細かい話は置いとく)

f:id:manma_shiro:20200114203002p:plain

呼び側からは見えなくなった

setter/getter作った変数ぐらいは、initで初期化したほうがいいと思うのと、setterぐらい明確なメソッドの引数はvalueでも十分なので変更した。

ちなみに
上から順番に解釈されるので、setter/getterの順番を逆にすると定義されていませんエラーがでる

NameError: name 'foo' is not defined

pythonとかスクリプト言語にはまだ慣れていないので、単純なところで嵌りやすい。。。