cannot create my own dict

Bruno Desthuilliers bdesth.quelquechose at free.quelquepart.fr
Wed Sep 19 15:23:03 EDT 2007


A.T.Hofkamp a écrit :
> Hello all,
> 
> This morning I tried to create my own read-only dictionary, and failed
> miserably.
> I don't understand why, can somebody enlighten me?
> 
> Below is a brute-force experiment that cannot deal with "x in obj", plz read
> the explanation below the code:
> --------------------------------
> class myowndict(object):
>     def __init__(self, mydict):
>         self.mydict = mydict

Why don't you just subclass dict and override the needed method(s) ?

class ReadOnlyDict(dict):
     @classmethod
     def _raise(cls):
         raise AttributeError("%s is read-only" % cls.__name__)

     def __setitem__(self, name, val):
         self._raise()

     def setdefault(self, name, value=None):
         self._raise()

     # TODO : check if I missed some other setter ?

def test(d):
     print d
     try:
         d['c'] = 3
     except AttributeError, e:
         print "__setitem__ ok, got : %s" % e
     else:
         assert('failed on __setitem__')
     try:
         d.setdefault('c', 3)
     except AttributeError, e:
         print "setdefault ok, got : %s" % e
     else:
         assert('failed on setdefault')

if __name__ == '__main__':
     d1 = ReadOnlyDict(a=1, b=2)
     test(d1)

     d2 = ReadOnlyDict({'a':1, 'b':2})
     test(d2)

     d3 = ReadOnlyDict((c, i+1) for i, c in enumerate('ab'))
     test(d3)

    d4 = ReadOnlyDict(**d1)
    test(d4)

NB : works fine so far, but choke on fromkeys, which obviously uses 
__setitem__


> # Below is produced with
> # print '\n'.join(['        self.%s = self.mydict.%s' % (v,v)
> #                                         for v in dir(dict)])
> # commented-out functions done by hand
> #
>         #self.__class__ = self.mydict.__class__
>         self.__cmp__ = self.mydict.__cmp__
>         self.__contains__ = self.mydict.__contains__

(snip lots of useless code)

May I suggest that you learn to use __getattr__ and __setattr__ ?-)

HTH



More information about the Python-list mailing list