web-dev-qa-db-ja.com

TypeError:複数のベースにインスタンスレイアウトの競合があります

2つからクラスを作成したかった:collections.OrderedDictおよびcollections.DefaultDict。そのため、順序付けられた辞書を取得し、存在しないキーにアクセスするためのデフォルト値を設定できます。これを行う方法は何ですか?

私の解決策は、上記の2つのクラスの周りに別のクラスを作成することでした。これは私が思う同じ名前の各クラスのメソッドが原因でエラーになりますか?

from collections import defaultdict, OrderedDict
class owndic(OrderedDict, defaultdict):
    pass

生産

TypeError: multiple bases have instance lay-out conflict

乾杯!

13
user6046760

この例外は、Cレベルで互いに連携できない複数の組み込み型から継承しようとしているために発生します。これは、これらのクラスが類似の属性の機能で競合していることを意味します。この場合、OrderedDictdefaultdictは、2つの辞書のような型で、独自の一意の___setitem___属性を持ち、キーと値の処理方法も異なります。

Cレベルでは、このエラーは _best_base_ 関数が複数の基本クラスの中から最適なベースを計算できない場合に発生します。この関数が他のベースの中で最良のベースまたは勝者を計算できない原因は他にもいくつかありますが、この場合、以下の条件のいずれも発生しない場合にエラーが発生します。 winnerはNoneではなく、winnercandidateのサブタイプではありません*candidatewinnerのサブタイプではありません。

_candidate = solid_base(base_i);
if (winner == NULL) {
    winner = candidate;
    base = base_i;
}
else if (PyType_IsSubtype(winner, candidate))
    ;
else if (PyType_IsSubtype(candidate, winner)) {
    winner = candidate;
    base = base_i;
}
else {
    PyErr_SetString(
        PyExc_TypeError,
        "multiple bases have "
        "instance lay-out conflict");
    return NULL;

}
_

ただし、defaultdict()OrderedDict()の両方の機能を利用したい場合は、OrderedDictとその組み込みsetdefault属性を使用するだけで済みます。

次に例を示します。

_In [13]: d = OrderedDict()

In [14]: for i, j in enumerate(['k', 'r', 'k', 'j', 'j', 't']):
             d.setdefault(j, []).append(i)
   ....:     

In [15]: d
Out[15]: OrderedDict([('k', [0, 2]), ('r', [1]), ('j', [3, 4]), ('t', [5])])
_

* candidateは、クラス呼び出し元に渡される基底の1つである_base_i_の強固な基底であり、 _solid_base_ 関数を使用して計算されます。

15
Kasramvd