OrderedCounterがOrderedDict documentation例として与えられ、そして任意のメソッドをオーバーライドすることなく動作しているに表示される:クラスメソッドが呼び出されると
class OrderedCounter(Counter, OrderedDict):
pass
、Pythonがなければなりません実行する正しい方法を見つけてください。 「メソッド解決順序」またはmroと呼ばれるクラス階層を検索する定義済みの順序があります。 MROは、属性__mro__
に格納されます。
OrderedCounter.__mro__
(<class '__main__.OrderedCounter'>, <class 'collections.Counter'>, <class 'collections.OrderedDict'>, <class 'dict'>, <class 'object'>)
OrderedDictのインスタンスが__setitem__()
を呼び出して、それが順序でクラスを検索します。OrderedCounter
、(それが発見された)Counter
、OrderedDict
。したがって、oc['a'] = 0
のようなステートメントは、OrderedDict.__setitem__()
を呼び出して終了します。
対照的に、__getitem__
は、mroのサブクラスによってオーバーライドされないため、count = oc['a']
はdict.__getitem__()
によって処理されます。
oc = OrderedCounter()
oc['a'] = 1 # this call uses OrderedDict.__setitem__
count = oc['a'] # this call uses dict.__getitem__
より興味深い呼び出しシーケンスはCounter.update()
が呼び出される、oc.update('foobar').
ファーストのような文で発生します。 Counter.update()
のコードではself [elem]が使用され、OrderedDict.__setitem__()
が呼び出されます。 のコードはとなり、dict.__setitem__()
となります。
基本クラスを元に戻すと、元のクラスは元に戻りません。 mroは違っていて、間違ったメソッドが呼び出されるからです。 MROの
class OrderedCounter(OrderedDict, Counter): # <<<== doesn't work
pass
詳細情報は、Python 2.3 documentationで見つけることができます。
理解できないことについてもう少し具体的にすることはできますか? – mgilson
クラスはCounter、OrderedDictから継承していますが、これらのクラスを組み合わせてOrderedCounterを生成する方法はわかりません。カウンタ?これは私が求めていることを明確にするのに役立ちますか? – Sean
基本的に、経験則として、複数の継承を避けてください(あなたの同僚はあなたにこの方法であなたを殺しません)...(粗いミックスのものは少し異なります) –