我们可以通过多重继承轻松创建一个OrderedCounter:
那么,魔术的诀窍之所以奏效,是因为
起初我以为这可能是因为
为什么
而且为什么需要成为关键字参数?当在菱形继承情况下使用
>>> from collections import Counter, OrderedDict
>>> class OrderedCounter(Counter, OrderedDict):
... pass
...
>>> OrderedCounter('Mississippi').items()
[('M', 1), ('i', 4), ('s', 4), ('p', 2)]
如果我错了,请纠正我,但这关键取决于Counter
使用super
:
class Counter(dict):
def __init__(*args, **kwds):
...
super(Counter, self).__init__()
...
那么,魔术的诀窍之所以奏效,是因为
>>> OrderedCounter.__mro__
(__main__.OrderedCounter,
collections.Counter,
collections.OrderedDict,
dict,
object)
super
调用必须按照'siblings before parents' rule of the mro委托,因此自定义类使用OrderedDict
作为存储后端。然而,我的一位同事最近指出,令我惊讶的是,OrderedDict
没有使用super:def __setitem__(self, key, value,
dict_setitem=dict.__setitem__, proxy=_proxy, Link=_Link):
...
# <some weird stuff to maintain the ordering here>
dict_setitem(self, key, value)
起初我以为这可能是因为
OrderedDict
先存在,Raymond后来没有再更改它,但似乎super
比OrderedDict
还要早。为什么
OrderedDict
会显式地调用dict.__setitem__
呢?而且为什么需要成为关键字参数?当在菱形继承情况下使用
OrderedDict
时,这难道不会造成麻烦吗?因为它直接传递给父类,而不是委托给mro中的下一个类。
QueryDict
覆盖了__setitem__
,而collections.OrderedDict
则不支持协同继承。这种“微优化”带来的问题示例:https://stackoverflow.com/questions/23662247/can-i-make-django-querydict-preserve-ordering#comment78727560_41798570 - wim