I'm trying to get a grasp of inheritance in Python but am having problems.

I am trying to create a derived class but want the derived class to only provide an initialized instance of the base class. Specifically I would like to inherit from OrderedDict as shown in the following example.

from odict import *

class ItemTableA(OrderedDict):
    def __init__(self):
        self = OrderedDict()
        self.update( [ ('ITEM1', [(1, 8), 111]) ]  )
        self.update( [ ('ITEM2', [(1, 8), 222]) ]  )
        self.update( [ ('ITEM3', [(1, 8), 333]) ]  )

class ItemTableB(OrderedDict):
    def __init__(self):
        self = OrderedDict()
        self.update( [ ('ITEM1', [(1, 16), 111]) ]  )
        self.update( [ ('ITEM2', [(1, 16), 222]) ]  )
        self.update( [ ('ITEM3', [(1, 32), 333]) ]  )

if __name__ == '__main__':
    myTable = ItemTableA()
    print type(myTable)         # P1
    print myTable               # P2
    print myTable['ITEM2']      # P3
    print  myTable.keys()       # P4

I expect the print statement output to be something like:

<class '__main__.ItemTable'>
OrderedDict([('ITEM1',[(1,8),111]),('ITEM2',[(1,8),222]),('ITEM3',[(1,8),333])] )
['ITEM1', 'ITEM2', 'ITEM3']

Instead, when I run this program the last 3 print statements fail. Please cut-n-paste-run to see exceptions.

I suspect it's an operator error in the __init__() statement.
Any ideas? Does my attempt to create a bunch of initialized tables make sense? (perhaps there's a better way)


Well, I don't have an 'odict' module, so my error message was on line 1. :)

Below is an example of how to do inheritance correctly. If you uncomment lines 21 and 24, you should get an error message similar to the one you were getting.

Basically, the problem with your code is that in __init__, you were clobbering self with a new OrderedDict() object. But then when __init__ returns, its namespace disappears (i.e., all variables are garbage collected), and the change you made is entirely lost.

By contrast, in the WellChild() object below, WellChild's __init__ calls the parent's __init__() -- this should (almost) ALWAYS be done by children. The Parent.__init__ then sets up all of the inherited data members.

The super(type, instance) function looks up the parent of WellChild. Or, you can do it manually as I indicated in the comment. [Note: the documentation on super() is wrong :(. It shows super(type), but an instance is also required].

Hope that helps.

class Parent(object):
    def __init__(self):
        self.a = "A"
        self.b = "B"

    def __str__(self):
        return self.a + self.b

class BrokenChild(Parent):
    def __init__(self):
        self = Parent()

class WellChild(Parent):
    def __init__(self):
        super(WellChild, self).__init__()
        # OR,
        # Parent.__init__()

a = Parent()
#b = BrokenChild()
c = WellChild()
print a
#print b
print c