How to subclass an OrderedDict?
Question:
Subclassing a Python dict
works as expected:
>>> class DictSub(dict):
... def __init__(self):
... self[1] = 10
...
>>> DictSub()
{1: 10}
However, doing the same thing with a collections.OrderedDict
does not work:
>>> import collections
>>> class OrdDictSub(collections.OrderedDict):
... def __init__(self):
... self[1] = 10
...
>>> OrdDictSub()
(…)
AttributeError: 'OrdDictSub' object has no attribute '_OrderedDict__root'
Thus, the OrderedDict implementation uses a private __root
atribute, which prevents the subclass OrdDictSub
from behaving like the DictSub
subclass. Why? How can one inherit from an OrderedDict?
Answers:
Try initializing the superclass in the __init__
method:
def __init__(self):
collections.OrderedDict.__init__(self)
self[1] = 10
This is the normal way to initialize a subclass. You don’t have to call the superclass’s __init__
method in general, but if you have no knowledge of the superclass’s implementation you really should call __init__
.
You need to invoke OrderedDict.__init__
from your __init__
:
class OrdDictSub(collections.OrderedDict):
def __init__(self):
super(OrdDictSub, self).__init__()
You haven’t given OrderedDict
a chance to initialize itself. Technically, you want to do this for your dict
subclass as well, since you want a fully initialized dict
. The fact that dict
works without it is just luck.
Subclassing a Python dict
works as expected:
>>> class DictSub(dict):
... def __init__(self):
... self[1] = 10
...
>>> DictSub()
{1: 10}
However, doing the same thing with a collections.OrderedDict
does not work:
>>> import collections
>>> class OrdDictSub(collections.OrderedDict):
... def __init__(self):
... self[1] = 10
...
>>> OrdDictSub()
(…)
AttributeError: 'OrdDictSub' object has no attribute '_OrderedDict__root'
Thus, the OrderedDict implementation uses a private __root
atribute, which prevents the subclass OrdDictSub
from behaving like the DictSub
subclass. Why? How can one inherit from an OrderedDict?
Try initializing the superclass in the __init__
method:
def __init__(self):
collections.OrderedDict.__init__(self)
self[1] = 10
This is the normal way to initialize a subclass. You don’t have to call the superclass’s __init__
method in general, but if you have no knowledge of the superclass’s implementation you really should call __init__
.
You need to invoke OrderedDict.__init__
from your __init__
:
class OrdDictSub(collections.OrderedDict):
def __init__(self):
super(OrdDictSub, self).__init__()
You haven’t given OrderedDict
a chance to initialize itself. Technically, you want to do this for your dict
subclass as well, since you want a fully initialized dict
. The fact that dict
works without it is just luck.