【问题标题】:Multiple inheritance of cython cdef classescython cdef 类的多重继承
【发布时间】:2018-10-06 22:51:03
【问题描述】:

我有一些类在 cython 中实现为 cdef class。在客户端 python 代码中,我想组合具有多重继承的类,但我遇到了类型错误。这是一个最小的可重现示例:

In [1]: %load_ext cython

In [2]: %%cython
   ...: cdef class A:
   ...:     cdef int x
   ...:     def __init__(self):
   ...:         self.x = 0
   ...: cdef class B:
   ...:     cdef int y
   ...:     def __init__(self):
   ...:         self.y = 0
   ...: 

In [3]: class C(A, B):
   ...:     pass
   ...: 
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-83ef5091d3a6> in <module>()
----> 1 class C(A, B):
      2     pass

TypeError: Error when calling the metaclass bases
    multiple bases have instance lay-out conflict

有没有办法解决这个问题?

docs 这么说:

一个 Python 类可以从多个扩展类型继承,前提是遵循多继承的常用 Python 规则(即所有基类的 C 布局必须兼容)。

鉴于上面的简单示例,我试图理解这可能意味着什么。

【问题讨论】:

    标签: python cython multiple-inheritance


    【解决方案1】:

    这是相当有限的。尽我所能告诉所有人,除了其中一个类必须是空的。空类可以有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;
     };
    

    本质上只是一个包含基本 Python 对象的 C 结构和一个整数。 限制是派生类必须只包含一个PyObject_HEAD,并且它的PyObject* 也应该可以解释为struct __pyx_obj_2bc_A*struct __pyx_obj_2bc_B*

    在您的情况下,两个整数 xy 将尝试占用相同的内存(因此冲突)。但是,如果其中一种类型为空,则它们将共享 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 持有AB 对象,而不是从AB 继承)

    【讨论】:

      猜你喜欢
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-27
      • 2017-02-04
      • 2015-01-18
      相关资源
      最近更新 更多