gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 06:34:15 24 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 中做更复杂的事情真的没有任何好处......)。

有一些明智的解决方法:

  • 新闻组帖子中建议的解决方法就是使用 python 列表。您还可以使用带有 dtype=object 的 numpy 数组。 .如果您需要访问类中的 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对象等并不像你想象的那么低效。
  • 另一种可能性是将您的数据存储为 C 结构 (cdef struct ChildStruct: ....),它可以很容易地存储为数组。当您需要该结构的 Python 接口(interface)时,您可以定义 Child所以它包含 ChildStruct 的副本(但修改不会传播回您的原始数组),或指向 ChildStruct 的指针(但您需要注意确保未释放 Child 指向它的内存是事件的)。
  • 您可以使用 Numpy structured array - 这与使用 C 结构数组非常相似,除了 Numpy 处理内存并提供 Python 接口(interface)。
  • 您问题中的 memoryview 语法有效: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 - 这是对底层 dtype 的诚实)
  • 关于cython:你如何创建一个 cdef 类的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33851333/

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