Python勉強メモ:特殊メソッド__getattribute__とは?
Pythonを勉強しているなかで、特殊メソッド__getattribute__に遭遇したので、ちょっと調べてみた。
どうやら、__getattribute__のほかにも、__getattr__なるものがあるらしい。
・__getattr__:未定義のメンバーにアクセスする際に呼び出される。
・__getattribute__:未定義・定義済み関わらず、すべてのメンバーアクセスで呼び出される。
◆特殊メソッド __getattribute__
まずは、__getattribute__サンプルとして、test_getattribute.py で試してみた。
import sys class A(object): def __init__(self): print "aaa0" def a1(self): print "aaa1" class B(A): def __init__(self): print "bbb0" def b1(self): print "bbb1" def __getattribute__(self,name): try: print "getattribute:name=%s"%name return object.__getattribute__(self, name) except: print "undefined method" sys.exit() if __name__ == '__main__': t1=B() t1.b1() print "------" t2=B() t2.a1() print "------" t3=B() t3.c1()
test_getattribute.py を動かしてみた。
$ python test_getattribute.py bbb0 getattribute:name=b1 bbb1 ------ bbb0 getattribute:name=a1 aaa1 ------ bbb0 getattribute:name=c1 undefined method
継承クラス関係のいずれのメソッドにアクセスした場合でも、必ず、__getattribute__が呼び出されているし、
さらに、未定義メソッドにアクセスした場合でも、__getattribute__が呼び出されている様子がわかると思います。
◆特殊メソッド __getattr__
つぎに、__getattr__サンプルとして、test_getattr.py で試してみた。
import sys class A(object): def __init__(self): print "aaa0" def a1(self): print "aaa1" class B(A): def __init__(self): print "bbb0" def b1(self): print "bbb1" def __getattr__(self,name): try: print "getattr:name=%s"%name return object.__getattr__(self, name) except: print "undefined method" sys.exit() if __name__ == '__main__': t1=B() t1.b1() print "------" t2=B() t2.a1() print "------" t3=B() t3.c1()
test_getattr.py を動かしてみた。
$ python test_getattr.py bbb0 bbb1 ------ bbb0 aaa1 ------ bbb0 getattr:name=c1 undefined method
単に、未定義メソッドにアクセスした場合に限り、__getattr__が呼び出されている様子がわかると思います。
◆おわりに
継承クラス関係における子クラスで、__getattribute__を定義しておけば、いずれのメソッドへのアクセスが発生したのかを一元的に観測できるようになる。確かに便利そうだと理解できた。