pythonには__getattr__の他に__getattribute__なんてものがあるらしい。

2014-04-23 追記

setattrについての記事もどうぞ。

pythonでtest.aみたいなアクセスの仕方をする時、実は裏側では__gettattr__(test, 'a')なんてメソッドが呼ばれてるらしい。 ただのクラスメソッドなので、上書きして自由自在に黒魔術出来ます。楽しいね。

で、気になったのが

>>> dir(object)
['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']

__getattribute__なんてメソッドがある。なんだこれ。

調べてもよくわからないので、色々実験してみました。

class tea(object):
    ''' this is document '''

    def __getattribute__(self, name):
        print 'attribute!'
        try:
            return object.__getattribute__(self, name)
        except Exception as e:
            print repr(e)
            raise

    def __getattr__(self, name):
        print 'attr!'
        return 'attr!'

print '--- a ---'
x = repr(tea().a)
print 'return', x
print
print '--- __doc__ ---'
x = repr(tea().__doc__)
print 'return', x

こんなスクリプトを書いて実行。

結果は

--- a ---
attribute!
AttributeError("'tea' object has no attribute 'a'",)
attr!
return 'attr!'

--- __doc__ ---
attribute!
return ' this is document '

こんな感じ。

推測するに、 とりあえず__getattribute__を呼んでみて、なんか返ってきたらそのまま返却。AttributeErrorが送出されたら__getattr__を探して、見つかったら呼んでみる。 みたいな流れなんじゃないでしょうか。多分。

出来るだけ__getattr__を使ったほうが安全そうですね。