pythonの__setattr__をオーバーライドしてみたら楽しいかもしれない。
昨日の__getattr__
に引き続いてメタプログラミングシリーズですよ。
調子に乗るとグチャグチャになるのでほどほどに。
getattr関数と並び立つ(?)のがsetattr関数。 その名の通り、クラスインスタンスに値をセットできます。
値じゃなくて関数もセット出来るのだけれど、バインドされないのでちょっと面倒臭い。
バインドされないと何が起こるかというと、instance.method()
って呼び出し方をしてもselfが渡されないので、selfが必要ならinstance.method(instance)
ってやらないとになっちゃう。
まあそんな事はともかくだ。
setattr(a, 'key', value)
とすると、内部的にはa.__setattr__('key', value)
みたいに処理されているらしい。
しかも、a.key = value
とした場合も__setattr__
が呼ばれているみたい。
この__setattr__
ってやつも普通に上書きできるので、
>>> class Test(object): ... def __setattr__(self, key, value): ... print key, '<=', value ... >>> a = Test() >>> a.test = 123 test <= 123 >>> a.test Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Test' object has no attribute 'test'
代入できないクラス的な事ができる。どうでもいいね。
何かしら処理をした上で代入したい場合は
>>> class Double(object): ... def __setattr__(self, key, value): ... object.__setattr__(self, key, value*2) ... >>> a = Test() >>> a.one = 1 >>> a.one 2 >>> a.two = 2 >>> a.two 4
みたいな感じになります。入れた値が倍になる謎クラス。
当然普通の関数として書けるので、かなり自由っぽい。
ただ気をつけなきゃいけないのは、self.var = value
みたいな記述。無限ループするからね。