gpt4 book ai didi

cython:如何创建 cdef 类的数组

转载 作者:太空宇宙 更新时间:2023-11-03 21:18:21 25 4
gpt4 key购买 nike

我想要一个 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()

最佳答案

答案是否定的 - 这实际上不可能以一种有用的方式:newsgroup post of essentially the same question

不可能有 Child 的直接数组(分配在单个 block 中) s。部分原因是,如果其他地方引用了 Child在数组中,Child必须保持事件状态(但不是整个数组),这无法确保它们是否都分配在同一 block 内存中。此外,如果要调整数组大小(如果这是必需的),那么对数组中对象的任何其他引用都会无效。

因此,您只剩下一个指向 Child 的指针数组。 。这样的结构很好,但内部看起来几乎与 Python 列表一模一样(因此在 Cython 中做更复杂的事情实际上没有任何好处......)。

有一些明智的解决方法:

  1. 新闻组帖子中建议的解决方法就是使用 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()

    在内部,这两个选项都存储为 PyObject 的 C 数组。指向您的Child对象等并不像您想象的那样低效。

  2. 另一种可能是将数据存储为 C 结构体 ( cdef struct ChildStruct: .... ),它可以轻松存储为数组。当您需要该结构的 Python 接口(interface)时,您可以定义 Child所以它包含 ChildStruct 的副本(但修改不会传播回原始数组),或指向 ChildStruct 的指针(但是您需要小心确保 Child 指向它的内存未被释放)。

  3. 您可以使用 Numpy structured array - 这与使用 C 结构数组非常相似,只不过 Numpy 处理内存并提供 Python 接口(interface)。

  4. 您问题中的内存 View 语法有效:cdef Child[:] array_of_child 。这可以从 dtype object 的 numpy 数组初始化。 :

    array_of_child = np.array([(Child() for i in range(100)])

    就数据结构而言,这是一个指针数组(即与 Python 列表相同,但可以是多维的)。它避免了 <Child> 的需要铸件。它不做的重要事情是任何类型的类型检查 - 如果您提供的对象不是Child到数组中,那么它不会注意到(因为底层 dtypeobject ),但会给出无意义的答案或段错误。

    在我看来,这种方法会给你一种关于两件事的错误的安全感:首先,你已经创建了一个更高效的数据结构(你没有,它基本上与列表相同);其次,你有任何类型的安全性。然而,它确实存在。 (如果您想使用内存 View ,例如对于多维数组,最好使用 object 类型的内存 View - 这对底层数据类型是诚实的)

关于cython:如何创建 cdef 类的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54514844/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com