为什么 OrderedDict 不使用 super?

Why doesn't OrderedDict use super?

我们可以通过使用多重继承简单地创建一个OrderedCounter

>>> from collections import Counter, OrderedDict
>>> class OrderedCounter(Counter, OrderedDict): 
...     pass
...
>>> OrderedCounter('Mississippi').items()
[('M', 1), ('i', 4), ('s', 4), ('p', 2)]

如果我错了请纠正我,但这关键取决于 Counter uses super:

class Counter(dict):
    def __init__(*args, **kwds):
        ...
        super(Counter, self).__init__()
        ...

也就是说,这个魔术奏效了,因为

>>> OrderedCounter.__mro__
(__main__.OrderedCounter,
 collections.Counter,
 collections.OrderedDict,
 dict,
 object)

super 调用必须根据 mro 的 'siblings before parents' 规则进行委托,因此自定义 class 使用 OrderedDict 作为存储后端。

然而一位同事最近指出,令我惊讶的是,OrderedDict doesn't 使用超级:

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__

为什么它需要是一个 kwarg?在菱形继承情况下使用 OrderedDict 时,这不会造成麻烦吗,因为它直接传递给父 class 而不是委托给 mro 中的下一行?

这是一个微优化。查找 dict_setitem 参数比查找 dict.__setitem__super().__setitem__.

稍微快一些

如果您有另一个覆盖 __setitem__ 的 class,这可能会导致多重继承问题,但 OrderedDict 无论如何都不是为那种菱形结构方法覆盖而设计的。 OrderedDict 要支持它,它必须非常小心地保证另一个 class 的方法可能会看到什么,如果他们试图索引 OrderedDict 而排序信息与字典结构。这样的保证太麻烦了。