Python class that acts like a dict

I want to write a custom class that behaves like a dict - so I inherit from dict .

My question, however, is this: do I need to create a private dict member in my __init__() method? I don't see the point in this, since I already have dict behavior if I just inherit from dict .

Can someone point out why most inheritance fragments look like below?

 class CustomDictOne(dict): def __init__(self): self._mydict = {} # other methods follow 

Instead of simple ...

 class CustomDictTwo(dict): def __init__(self): # initialize my other stuff here ... # other methods follow 

In fact, I think I suspect that the answer to the question is that users cannot directly access your dictionary (i.e. they need to use the access methods you provide).

However, what about the array access operator [] ? How to implement this? So far I have not seen an example that shows how to override the [] operator.

So, if the accessor function [] not provided in the user class, will the inherited base methods work in another dictionary?

I tried the following snippet to test my understanding of Python inheritance:

 class myDict(dict): def __init__(self): self._dict = {} def add(self, id, val): self._dict[id] = val md = myDict() md.add('id', 123) print md[id] 

I got the following error:

KeyError: <built-in id function>

What is wrong with the code above?

How do I fix the myDict class myDict that I can write such code?

 md = myDict() md['id'] = 123 

[change]

I edited the above code example to get rid of the stupid mistake I made before I left my desk. It was a typo (I should have noticed it from the error message).

+92
python dictionary
Oct 25 2018-10-10
source share
5 answers

Check the documentation for container type emulation . In your case, the first add parameter should be self .

+32
Oct. 25 2018-10-25
source share
 class Mapping(dict): def __setitem__(self, key, item): self.__dict__[key] = item def __getitem__(self, key): return self.__dict__[key] def __repr__(self): return repr(self.__dict__) def __len__(self): return len(self.__dict__) def __delitem__(self, key): del self.__dict__[key] def clear(self): return self.__dict__.clear() def copy(self): return self.__dict__.copy() def has_key(self, k): return k in self.__dict__ def update(self, *args, **kwargs): return self.__dict__.update(*args, **kwargs) def keys(self): return self.__dict__.keys() def values(self): return self.__dict__.values() def items(self): return self.__dict__.items() def pop(self, *args): return self.__dict__.pop(*args) def __cmp__(self, dict_): return self.__cmp__(self.__dict__, dict_) def __contains__(self, item): return item in self.__dict__ def __iter__(self): return iter(self.__dict__) def __unicode__(self): return unicode(repr(self.__dict__)) o = Mapping() o.foo = "bar" o['lumberjack'] = 'foo' o.update({'a': 'b'}, c=44) print 'lumberjack' in o print o In [187]: run mapping.py True {'a': 'b', 'lumberjack': 'foo', 'foo': 'bar', 'c': 44} 
+91
Jun 01 '14 at 5:10
source share

Like this

 class CustomDictOne(dict): def __init__(self,*arg,**kw): super(CustomDictOne, self).__init__(*arg, **kw) 

Now you can use the built-in functions like dict.get() like self.get() .

You do not need to wrap a hidden self._dict . Your class already has a dict.

+70
Oct. 25 2018-10-25
source share

For completeness, here is a link to the documentation mentioned by @ björn-pollex for the latest Python 2.x (2.7.7 at the time of writing):

Container Type Emulation

(Sorry for not using the comment function, I'm just not allowed to do this with stackoverflow.)

+9
Jun 25 '14 at 13:50
source share

The problem with this piece of code:

 class myDict(dict): def __init__(self): self._dict = {} def add(id, val): self._dict[id] = val md = myDict() md.add('id', 123) 

... is that your add method (... and any method that you want to be a member of a class) must have an explicit self declared as its first argument, for example:

 def add(self, 'id', 23): 

To implement operator overloading to access items by key, look at the docs for the __getitem__ and __setitem__ magic methods.

Note that since Python uses Duck Typing, there really can be no reason to get your custom dict class from the dict class language - no longer knowing what you are trying to do (for example, if you need to pass an instance of that class to which is the code that will be broken if isinstance(MyDict(), dict) == True ), you might be better off just implementing an API that will make your class dictate enough and stop there.

+3
Oct 25 2018-10-25
source share



All Articles