我們可以通過使用多重繼承平凡創建OrderedCounter
:OrderedDict爲什麼不使用超級?
>>> 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
調用必須根據'兄弟姐妹befo父母的規則mro,自定義班級使用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
是先和雷蒙德沒有理會後來去改變它,但似乎super
早於OrderedDict
。
爲什麼OrderedDict
顯式調用dict.__setitem__
?
爲什麼它需要成爲一個kwarg?這在鑽石繼承情況下使用OrderedDict
時不會造成麻煩,因爲它直接傳遞給父類,而不是委託給mro中的下一行?
Django的'QueryDict'覆蓋'__setitem__','collections.OrderedDict'不會執行協作式繼承。由此「微優化」導致的問題示例:https://stackoverflow.com/questions/23662247/can-i-make-django-querydict-preserve-ordering#comment78727560_41798570 – wim