4

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)

呼び出しは、 mrosuperの「親の前に兄弟」ルールに従って委任する必要があります。そのため、カスタム クラスはストレージ バックエンドとして を使用します。 OrderedDict

しかし、同僚が最近指摘したのですが、驚いたことに、それはsuper を使用してOrderedDict いません:

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 の次の行に委任するのではなく、親クラスに直接渡すため、ダイヤモンド継承の状況で使用するときに問題を引き起こしませんか?

4

1 に答える 1