Class.__class__ magic trick help

Massimo Di Pierro massimo.dipierro at gmail.com
Tue Aug 21 00:17:15 EDT 2012


Consider this code:

class SlowStorage(dict):
    def __getattr__(self,key):
          return self[key]
    def __setattr__(self,key):
          self[key]=value

class FastStorage(dict):
    def __init__(self, __d__=None, **kwargs):
        self.update(__d__,**kwargs)
    def __getitem__(self,key):
        return self.__dict__.get(key,None)
    def __setitem__(self,key,value):
        self.__dict__[key] = value
    def __delitem__(self,key):
        delattr(self,key)
    def __copy__(self):
        return Storage(self)
    def __nonzero__(self):
        return len(self.__dict__)>0
    def pop(self,key,default=None):
        if key in self:
            default = getattr(self,key)
            delattr(self,key)
        return default
    def clear(self):
        self.__dict__.clear()
    def __repr__(self):
        return repr(self.__dict__)
    def keys(self):
        return self.__dict__.keys()
    def values(self):
        return self.__dict__.values()
    def items(self):
        return self.__dict__.items()
      def iterkeys(self):
        return self.__dict__.iterkeys()
    def itervalues(self):
        return self.__dict__.itervalues()
    def iteritems(self):
        return self.__dict__.iteritems()
    def viewkeys(self):
        return self.__dict__.viewkeys()
    def viewvalues(self):
        return self.__dict__.viewvalues()
    def viewitems(self):
        return self.__dict__.viewitems()
    def fromkeys(self,S,v=None):
        return self.__dict__.fromkeys(S,v)
    def setdefault(self, key, default=None):
        try:
            return getattr(self,key)
        except AttributeError:
            setattr(self,key,default)
            return default
    def clear(self):
        self.__dict__.clear()
    def len(self):
        return len(self.__dict__)
    def __iter__(self):
        return self.__dict__.__iter__()
    def has_key(self,key):
        return key in self.__dict__
    def __contains__(self,key):
        return key in self.__dict__
    def update(self,__d__=None,**kwargs):
        if __d__:
            for key in __d__:
                kwargs[key] = __d__[key]
        self.__dict__.update(**kwargs)
    def get(self,key,default=None):
        return getattr(self,key) if key in self else default

>>> s=SlowStorage()
>>> a.x=1  ### (1)
>>> a.x    ### (2)
1 # ok
>>> isinstance(a,dict)
True # ok
>>> print dict(a)
{'x':1} # ok (3)


>>> s=FastStorage()
>>> a.x=1  ### (4)
>>> a.x    ### (5)
1 # ok
>>> isinstance(a,dict)
True # ok
>>> print dict(a)
{} # not ok (6)

Lines (4) and (5) are about 10x faster then lines (1) and (2). I like
FastStorage better but while (3) behaves ok, (6) does not behave as I
want.

I intuitively understand why FastStorage is cannot cast into dict
properly.

What I do not know is how to make it do the casting properly without
losing the 10x speedup of FastStorage over SlowStorage.

Any idea?



More information about the Python-list mailing list