TypeError: multiple bases have instance lay-out conflict

前端 未结 1 1015
心在旅途
心在旅途 2021-02-19 00:36

I wanted to create a class out of two: collections.OrderedDict and collections.DefaultDict. So that I can get an ordered dictionary and have a default

1条回答
  •  伪装坚强ぢ
    2021-02-19 01:25

    Instance lay-out conflict is a fancy way of saying that you're trying to inherit from multiple--in this case built-in--types that cannot cooperate with each other quite well. More technically these classes have conflict in functionality of their common attributes.

    In this case both OrderedDict and defaultdict are two dictionary-like types with their own unique __setitem__ attributes and also different ways of handling the keys and values.

    At C level this error happens when the best_base function fails to calculate the best base amongst multiple base classes. There are multiple other reasons that can cause this function fail to calculate the best base or winner among other bases but in this case the error occurs when neither of following conditions happen. winner is not None, winner is not a subtype of candidate*, candidate is not a subtype of 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;
    
    }
    

    However, if you want to benefit from both defaultdict() and OrderedDict()'s functionalities, you can simply use an OrderedDict and its built-in setdefault attribute.

    Here is an example:

    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` is the solid base of `base_i`,one of the bases passed to the class caller, that is calculated using [`solid_base`](https://github.com/python/cpython/blob/ce5b0e9db1b9698e6ffc43ae41cf3a22ca5a6ba6/Objects/typeobject.c#L2086) function.

    0 讨论(0)
提交回复
热议问题