at_yasu's blog

ロード的なことを

__setattr__

ドキュメント読まずにpythonをいじくり回してるから無限ループに陥る馬鹿がここにおります。


classAを作った際、プロパティ*1で変数にアクセスしたい場合、ins.a とします。その時、Python内部では、instance.__getattr__(key)と呼ぶわけなのですが、内部でもself.__getattr__(key)と呼ぶので無限ループに陥るのです。

> class classA:
>   def __init__(self):
>     self.dict = dict()
>   def __setattr__(self,key,val):
>     self.dict[key] = val
>   def __getattr__(self,key):
>     return self.dict[key]
> a = classA()
> a.f = ''
...無限ループ..
RuntimeError: maximum recursion depth exceeded in cmp

回避方法はちゃんとドキュメントに載ってまして、self.__dict__と書けば、__dict__は__getattr__を呼ばないらしいので、そのように書けばいいようです。

> class classA:
>   def __init__(self):
>     self.__dict__ = dict()
>   def __setattr__(self,key,val):
>     self.__dict__[key] = val
>   def __getattr__(self,key):
>     return self.__dict__[key]
> a = classA()
> a.f = ''


参考:http://www.python.jp/doc/release/ref/attribute-access.html

*1:Pythonだと、attr?