OrderedDict won't sort within a class
Question: I have a parent class, and I want to keep a registry (in the form of a
dictionary) of all instances of its sub-classes. Easy, but I want the registry
to sort itself based on its keys, which are the arguments of the 2 sub-classes
on initialisation. This is my code in simplified form:

    
    
    from collections import OrderedDict
    
    class Parent:
        _registry = OrderedDict()
        def __init__(self):
            # add each sub-class instance to the registry & sort the registry
            self._registry.update({self._num:self})
            self._registry = OrderedDict(sorted(self._registry.items()))
    
    class Foo(Parent):
        def __init__(self, number):
            self._num = number
            Parent.__init__(self)
            # then do some stuff
    
    class Bar(Parent):
        def __init__(self, number):
            self._num = number
            Parent.__init__(self)
            # then do some other stuff
    ...
    

But, although the registry updates itself with the new sub-class objects, it
does not sort itself.

    
    
    >>> a = Foo(3)
    >>> Parent._registry # check to see if a was added to the registry
    OrderedDict([(3, <Foo instance at 0x00A19C0C8>)])
    >>> b = Bar(1)
    >>> Parent._registry # check to see if b was inserted before a in the registry
    OrderedDict([(3, <Foo instance at 0x00A19C0C8>), (1, <Bar instance at 0x00A19C1C8>)])
    

`b` comes after `a` in the registry!

If I do it manually in the iPython console, it works:

    
    
    >>> Parent._registry = OrderedDict(sorted(Parent._registry.items()))
    OrderedDict([(1, <Bar instance at 0x00A19C1C8>), (3, <Foo instance at 0x00A19C0C8>)])
    

Why won't it sort itself? I need it to, because later on, things have to
happen to those objects in strict order of their `number` arguments.


Answer: That's because:

    
    
    self._registry = OrderedDict(sorted(self._registry.items()))
    

creates a new attrbute on the instance, this doesn't affect
`Parent._registry`.

Replace that line with:

    
    
    Parent._registry = OrderedDict(sorted(self._registry.items()))
    

Here `self._registry.items()` can fetch the value of `Parent._registry` but
that doesn't mean assignment to `self._registry` will affect
`Parent._registry`.

* * *

Another way to do it using `self._registry` itself:

    
    
    def __init__(self):
        items = sorted(self._registry.items() + [(self._num, self)]) #collect items
        self._registry.clear() #clean the dict
        self._registry.update(items) #now update it
    

