我有一个父类,我想保留其子类的所有实例的注册表(以字典的形式)。很容易,但我希望注册表根据其键进行排序,这些键是初始化时2个子类的参数。这是我的简化代码:
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
...
但是,虽然注册表使用新的子类对象更新自身,但它不会自行排序。
>>> 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
来自注册表中的a
!
如果我在iPython控制台中手动执行,它可以工作:
>>> Parent._registry = OrderedDict(sorted(Parent._registry.items()))
OrderedDict([(1, <Bar instance at 0x00A19C1C8>), (3, <Foo instance at 0x00A19C0C8>)])
为什么不自行排序?我需要它,因为稍后,必须按照number
参数的严格顺序对这些对象进行操作。
答案 0 :(得分:3)
那是因为:
self._registry = OrderedDict(sorted(self._registry.items()))
在实例上创建新的attrbute,这不会影响Parent._registry
。
将该行替换为:
Parent._registry = OrderedDict(sorted(self._registry.items()))
此处self._registry.items()
可以获取Parent._registry
的值,但这并不意味着分配给self._registry
会影响Parent._registry
。
使用self._registry
本身的另一种方法:
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