Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to subclass an OrderedDict?

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?

like image 929
Eric O Lebigot Avatar asked Jun 24 '12 03:06

Eric O Lebigot


People also ask

How do you define OrderedDict?

An OrderedDict is a dictionary subclass that remembers the order in which its contents are added. A regular dict does not track the insertion order, and iterating over it produces the values in an arbitrary order.

How does OrderedDict work in Python?

Python's OrderedDict is a dict subclass that preserves the order in which key-value pairs, commonly known as items, are inserted into the dictionary. When you iterate over an OrderedDict object, items are traversed in the original order. If you update the value of an existing key, then the order remains unchanged.

What is the difference between dict and OrderedDict?

The OrderedDict is a subclass of dict object in Python. The only difference between OrderedDict and dict is that, in OrderedDict, it maintains the orders of keys as inserted. In the dict, the ordering may or may not be happen. The OrderedDict is a standard library class, which is located in the collections module.

How do I create an empty OrderedDict in Python?

We can create an empty OrderedDict and add items to it. If we create an OrderedDict by passing a dict argument, then the ordering may be lost because dict doesn't maintain the insertion order. If an item is overwritten in the OrderedDict, it's position is maintained.


2 Answers

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.

like image 165
Ned Batchelder Avatar answered Sep 30 '22 17:09

Ned Batchelder


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__.

like image 44
Dietrich Epp Avatar answered Sep 30 '22 18:09

Dietrich Epp