问题
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.
回答1:
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
来源:https://stackoverflow.com/questions/26724650/ordereddict-wont-sort-within-a-class