cannot create my own dict

Peter Otten __peter__ at web.de
Wed Sep 19 09:09:54 EDT 2007


A.T.Hofkamp wrote:

> 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
> 
> # 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__
>         self.__delattr__ = self.mydict.__delattr__
>         self.__delitem__ = self.mydict.__delitem__
>         #self.__doc__ = self.mydict.__doc__
>         self.__eq__ = self.mydict.__eq__
>         self.__ge__ = self.mydict.__ge__
>         self.__getattribute__ = self.mydict.__getattribute__
>         self.__getitem__ = self.mydict.__getitem__
>         self.__gt__ = self.mydict.__gt__
>         self.__hash__ = self.mydict.__hash__
>         #self.__init__ = self.mydict.__init__
>         self.__iter__ = self.mydict.__iter__
>         self.__le__ = self.mydict.__le__
>         self.__len__ = self.mydict.__len__
>         self.__lt__ = self.mydict.__lt__
>         self.__ne__ = self.mydict.__ne__
>         #self.__new__ = self.mydict.__new__
>         self.__reduce__ = self.mydict.__reduce__
>         self.__reduce_ex__ = self.mydict.__reduce_ex__
>         self.__repr__ = self.mydict.__repr__
>         self.__setattr__ = self.mydict.__setattr__
>         self.__setitem__ = self.mydict.__setitem__
>         self.__str__ = self.mydict.__str__
>         self.clear = self.mydict.clear
>         self.copy = self.mydict.copy
>         self.fromkeys = self.mydict.fromkeys
>         self.get = self.mydict.get
>         self.has_key = self.mydict.has_key
>         self.items = self.mydict.items
>         self.iteritems = self.mydict.iteritems
>         self.iterkeys = self.mydict.iterkeys
>         self.itervalues = self.mydict.itervalues
>         self.keys = self.mydict.keys
>         self.pop = self.mydict.pop
>         self.popitem = self.mydict.popitem
>         self.setdefault = self.mydict.setdefault
>         self.update = self.mydict.update
>         self.values = self.mydict.values
> 
>         # end of __init__
> 
> if __name__ == '__main__':
>     fd = myowndict({1:10})
>     print 1 in fd  # FAILS! (with "TypeError: iterable argument required")
> --------------------------------
> 
> I wanted to make my own dictionary. However, a simple element test failed
> (after implementing various __*__ functions), and I cannot figure out why.
> 
> The above code is a brute force attempt, where I forward all methods (except
> __class__, __doc__, __init__, and __new__) to my local 'mydict' object.
> 
> IT STILL FAILS.

__special__ methods are looked up in the class, never in the instance for
newstyle classes:

>>> def class_method(self, *v): print "class"
... 
>>> def inst_method(*v): print "instance"
... 
>>> class B(object):
...     __contains__ = class_method
...     copy = class_method
...     def __init__(self):
...             self.__contains__ = inst_method
...             self.copy = inst_method
... 
>>> 42 in B()
class
False
>>> B().copy()
instance

> So if copying all methods of a native dictionary is not enough, what should I
> do to make my class work as a dictionary WITHOUT deriving from dict (which will
> obviously work).

Write wrappers like

def __contains__(self, value):
    return value in self.mydict

Peter



More information about the Python-list mailing list