<span class="gmail_quote"></span>overriding __getattr__ and __setattr__ has several negative side effects, for example:<br><div style="direction: ltr;">* inside__getattr__/__setattr__ you have to use self.__dict__["attr"] instead of
self.attr<br>* it's easy to get stack overflow exceptions when you do something wrong
<br>* you must remember to call the super's [get/set]attr or the MRO is broken<br>* when deriving from a class that overrides one of the speical methods, you usually<br>need to override the special function of your class as well, to allow some "local storage"
<br>for yourself<br><br>so i had an idea -- why not just replace __dict__? this does not affect the MRO. i wrote an <br>AttrDict class, which is like dict, only it allows you to acces its keys as attributes. i later <br>
saw something like this on the python cookbook as well.
<br><br>class AttrDict(dict):<br> def __init__(self, *a, **k):<br> dict.__init__(self, *a, **k)<br> self.__dict__ = self<br><br>this code basically causes __getattr/setattr__ to use __getitem/setitem__:<br>
a =AttrDict()<br>a["blah"] = 5<br>a.yadda = 6<br>print a.blah<br>print a["yadda"]<br><br>which is exactly what i wanted. now, i thought, instead of overriding __getattr/setattr__, i'd <br>just write a class that overrides __getitem/setitem__. for example:
<br><br># old way<br>class A(object):<br> def __getattr__(self, name):<br> return 5<br>a = A()<br>print a.xyz # 5<br><br># new way<br>class mydict(dict):<br> def __getitem__(self, key):<br> return 5<br>
class A(object):<br> def __init__(self):<br> self.__dict__ = mydict()<br>a = A()<br>print a.xyz # should print 5<br><br>but lo and behold, python does not call my overriden method. it just bypasses it and always
<br>calls the original dict's method. i made several tests, trying to see if it calls __contains__,<br>placed hooks on __getattribute__, but nothing from *my* overriden methods is ever called. <br>this is probably because the C implementation calls PyDict_GetItem or whatever directly...
<br><br>i think it's a bug. i should be able to override the __getitem__ of my __dict__. it breaks the <br>polymorphism of python-level objects! on the one hand, i'm allowed to change __dict__ to any<br>object that derives from dict, but i'm not allowed to override it's methods!
<br>python must either disable assigning to __dict__, or be willing to call overriden methods, not<br>silently ignore mine.<br></div><div style="direction: ltr;"><span class="sg"><br><br>-tomer
</span></div>