On Mon, Jan 30, 2012 at 10:49 AM, Massimo Di Pierro < massimo.dipierro@gmail.com> wrote:
STEP 4) class Dummy(object): def __getitem__(self,key): return getattr(self,key) def __setitem__(self,key,value): return setattr(self,key,value) def __getattr__(self,key): return object.__getattr__(self,key) if hasattr(self,key) else Dummy()
Is this un-pythonic?
I do not think so but I do have a problem with it:
class Dummy(object): def __getitem__(self,key): return getattr(self,key) def __setitem__(self,key,value): return setattr(self,key,value) def __getattr__(self,key): print 'wtf' return object.__getattr__(self,key) if hasattr(self,key) else None
d=Dummy() print d.somethingelse wtf ... 334 wtf times with python2.7, 999 times with python2.5... wtf None
getattr calls hasattr, which calls getattr again. You are hitting the recursion limit before failing the test, due to hasattr failing with a recursion error, thus returning false. You could refactor this to use exceptions, such as: def __getattr__(self, key): try: return object.__getattr__(self, key) except Exception: return None
whatever this does internally, it makes some programs slower then I would like them to be. Why is it calling itself 334 times?
STEP 5) We can add methods to make this object behave like a dictionary by redefining d.keys() in terms of d.__dict__.keys() etc.
STEP 6) we can re-factor it a bit so that actually class Dummy is derived from dict.
Is this the part that people do not like?
The general discontent with the idea is step 4. Doing so leads to abnormalities, such as d['clear'] != d.clear. The only ways to resolve such abnormalities are to make using any keys/attributes which conflict illegal, or to use different access methods for the two forms.
I would be happy if Python provided an efficient way to do something like STEP 4 without the problem I mentioned. Perhaps there is one and I ignore it. I do not necessarily require STEP5 and STEP6.
Use case:
settings = Dummy() settings.parameter1 = 'a' settings.parameter2 = 'b' etc.
if not settings.parameter1: do something ...
Massimo