cython:如何创建一个cdef类数组

Dav*_*jad 8 cython

我想有一个cdef类的cython数组:

cdef class Child:
    cdef int i

    def do(self):
        self.i += 1

cdef class Mother:
    cdef Child[:] array_of_child

    def __init__(self):
        for i in range(100):
            self.array_of_child[i] = Child()
Run Code Online (Sandbox Code Playgroud)

Dav*_*idW 11

答案是否定的 - 这是不可能的:新闻组的帖子基本上是同一个问题

本质上,数组必须是指向您的指针数组Child,而不是直接的Childs 数组.它几乎必须是这样的,因为其他地方曾经获得Child对数组中的a的引用,Child必须保持活动(但不是整个数组),如果它们全部分配在同一个数组中则无法确保大块的记忆.另外,如果要调整数组的大小(如果这是一个要求),那么它将使对数组中对象的任何其他引用无效.

有一些明智的工作环境:

  1. 新闻组帖子中建议的workround就是使用python列表.您也可以使用numpy数组dtype=object.如果您需要在类中访问cdef函数,可以先进行强制转换:

    cdef Child c = <Child?>a[0] # omit the ? if you don't want
                                # the overhead of checking the type.
    c.some_cdef_function()
    
    Run Code Online (Sandbox Code Playgroud)

    在内部,这两个选项都存储为PyObject指向Child对象的C数组,因此效率不如您所假设的那样低.

  2. 另一种可能性是将数据存储为C结构(cdef struct ChildStruct: ....),可以很容易地存储为数组.当你需要一个Python接口到那个结构时,你可以定义Child所以它包含一个副本ChildStruct(但修改不会传播回原始数组),或指向ChildStruct(但你要小心确保内存是没有释放,Child指向它是活着的).

  3. 你可以使用Numpy结构化数组 - 这非常类似于使用除Numpy处理内存之外的C结构数组,并提供Python接口.