Это довольно ограничено.Насколько я могу судить, все классы, кроме одного, должны быть пустыми.Пустые классы могут иметь def
функции, но не cdef
функции или cdef
атрибуты.
Взять класс Cython:
cdef class A:
cdef int x
Это переводит в C-код:
struct __pyx_obj_2bc_A { // the name might be different
PyObject_HEAD
int x;
};
По сути, просто структура C, содержащая базовый объект Python и целое число.Ограничение состоит в том, что производный класс должен содержать только один PyObject_HEAD
и что его PyObject*
также должен интерпретироваться как struct __pyx_obj_2bc_A*
или struct __pyx_obj_2bc_B*
.
В вашем случае два целых числа x
и y
будет пытаться занять одну и ту же память (поэтому конфликтует).Однако, если один из типов будет пустым, они будут совместно использовать PyObject_HEAD
, но не будут конфликтовать дальше.
cdef
функции приводят к добавлению struct __pyx_vtabstruct_2bc_A *__pyx_vtab;
в структуру (так что она не пустая).Он содержит указатели на функции, которые позволяют унаследованным классам переопределять функции cdef
.
Наличие двух cdef
классов, которые наследуются от общего третьего класса, - ОК, событие, если общий третий класс не пуст.
cdef class A:
cdef int x
cdef class B(A):
cdef int y
cdef class C(A):
pass
class D(B,C):
pass
Внутренний код Python, выполняющий эту проверку, является функцией best_base
, если вы действительно хотите изучить детали алгоритма.
Со ссылкой на "есть ли способ обойти это?"ответ "не совсем".Лучшим вариантом, вероятно, является композиция, а не наследование (т.е. класс C
содержит объект A
и B
, а не наследует от A
и B
)