views:

127

answers:

5

I want to write a custom class that behaves like dict - so, I am inheriting from dict.

My question though is that do I need to create a private dict member in my init() method?. I dont see the point of this, since I already have the dict behaviour if I simply inherit from dict.

Can anyone point out why most of the inheritance snippets look like this:

class CustomDictOne(dict):
   def __init__(self):
      self._mydict = {} 

   # other methods follow



Instead of the simpler

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

   # other methods follow

Actually, I think I suspect the answer to the question - is so that users cannot directly access your dictionary - i.e. they have to use the access methods that you have provided.

However, what about the array access operator [], how would one implement that - so far, I have not seen an example that shows how to override the [] operator.

So if an [] access function is not provided in the custom class, the inherited base methos will be operating on a different dictionary?

I tried the following snippet to test out 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 function id>

What is wrong with the code above?

How do I correct the class myDict so that I can write code like this:

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

[Edit]

I have edited the code sample above to get rid of the silly error I made before I dashed away from my desk. It was a typo (I should have spotted it from the error message).

+4  A: 

Check the documentation on emulating container types. In your case, the first parameter to add should be self.

Space_C0wb0y
A: 

You need to add self:

def add(self, id, val):
    self._dict[id] = val
Andrew Sledge
+2  A: 

Use UserDict rather than inheriting from dict and i think all your problem will be solve , if you want more detail on this let me know :)

you can see this for more detail about the advantage of UserDict : http://stackoverflow.com/questions/1392396/advantages-of-userdict-class-in-python

singularity
The need for this class [UserDict] has been largely supplanted by the ability to subclass directly from dict (a feature that became available starting with Python version 2.2). from http://docs.python.org/library/userdict.html
jsbueno
There is no point in extending UserDict instead of dict in this code - the op code is fundamentally flawed in several aspects, and just changing the superclass does not perform any magic.
jsbueno
+1  A: 

The problem with this chunk 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 you want to be a member of a class) needs to have an explicit 'self' declared as its first argument, like:

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

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

Note that because Python uses Duck Typing, there may actually be no reason to derive your custom dict class from the language's dict class -- without knowing more about what you're trying to do (e.g, if you need to pass an instance of this class into some code someplace that will break unless isinstance(MyDict(), dict) == True), you may be better off just implementing the API that makes your class sufficiently dict-like and stopping there.

bgporter
Note that the link that @singularity posted includes some cases where deriving your class from dict or UserDict do make sense -- again, the best choice depends on your actual application.
bgporter
+1  A: 

Like this

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

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

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

S.Lott
This. There's no point in inheriting from ``dict`` without calling its constructor first.
sykora