【问题标题】:TypeError: multiple bases have instance lay-out conflictTypeError:多个基地有实例布局冲突
【发布时间】:2018-06-16 14:08:55
【问题描述】:

我想从两个类中创建一个类:collections.OrderedDictcollections.DefaultDict。这样我就可以获得一个有序的字典,并为正在访问的不存在的键设置一个默认值。有什么方法可以做到这一点?

我的解决方案是围绕我上面提到的 2 个类创建另一个类。由于我认为每个类中的方法具有相同的名称,这会导致错误?

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

生产

TypeError: multiple bases have instance lay-out conflict

干杯!

【问题讨论】:

  • 您使用的是什么版本的 Python?我无法在 Python 3.4.2 上重现错误
  • 不管你的TypeError是什么原因,如果你想同时使用这两种功能,你最好使用OrderedDict,它的setdefault()属性与defaultdict具有相同的功能。
  • 这个错误似乎是因为defaultdictOrderedDict 都继承自内置的dict 类型(它们唯一的基本类型),这在python 中是不允许的。
  • 它在hackerrank中的python 3 - 没有说确切的版本。可爱,我会尝试setdefault 谢谢!

标签: python python-3.x class defaultdict


【解决方案1】:

Instance lay-out conflict 是一种奇特的说法,表示您正在尝试从多个无法很好地相互协作的类型(在这种情况下为内置类型)继承。从技术上讲,这些类在其共同属性的功能上存在冲突。

在这种情况下,OrderedDictdefaultdict 都是两个类字典类型,它们具有自己独特的 __setitem__ 属性以及处理键和值的不同方式。

在 C 级别,当 best_base 函数无法计算多个基类中的最佳基时会发生此错误。还有多种其他原因可能导致此函数无法计算其他基地中的最佳基地或获胜者,但在这种情况下,当以下两种情况均未发生时会发生错误。 winner 不是 None,winner 不是 candidate* 的子类型,candidate 不是 winner 的子类型。

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` 是 `base_i` 的坚实基础,是传递给类调用者的基础之一,使用 [`solid_base`] 计算(https://github.com/python/cpython/blob/ce5b0e9db1b9698e6ffc43ae41cf3a22ca5a6ba6/Objects /typeobject.c#L2086) 函数。

【讨论】:

    猜你喜欢
    • 2021-02-08
    • 2019-04-03
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 2016-04-16
    • 2014-03-01
    相关资源
    最近更新 更多