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
みたいな記述。無限ループするからね。