pythonには__getattr__の他に__getattribute__なんてものがあるらしい。
追記
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__
を使ったほうが安全そうですね。