cython:如何创建cdef类的数组
我想要一个cdef类的cython数组:cython:如何创建cdef类的数组,cython,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() 答案是否
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()
答案是否定的——这实际上不可能以一种有用的方式实现: 不可能有一个
Child
s的直接数组(在单个块中分配)。部分原因是,如果在其他地方获得了对数组中子项的引用,则该子项
必须保持活动状态(而不是整个数组),这将无法确保它们是否都分配在同一内存块中。此外,如果要调整数组的大小(如果这是一项要求),那么它将使对数组中对象的任何其他引用无效
因此,只剩下一组指向子对象的指针。这样的结构很好,但内部看起来几乎完全像Python列表(因此在Cython中执行更复杂的操作毫无益处…)
有几个合理的解决办法:
新闻组文章中建议的解决方法只是使用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()
就数据结构而言,这是一个指针数组(即与Python列表相同,但可以是多维的)。它避免了
铸造的需要。它不做的重要事情是任何类型的检查-如果你将一个不是子对象的对象输入数组,那么它不会注意到(因为底层dtype
是object
),但会给出无意义的答案或分段错误
在我看来,这种方法在两件事上给了你一种错误的安全感:首先,你已经建立了一个更高效的数据结构(你没有,它基本上与列表相同);第二,你有任何类型的安全。然而,它确实存在。(如果要使用memoryview,例如,对于多维数组,可能最好使用类型为object
的memoryview-这是对底层数据类型的诚实描述)
你有什么理由相信我的答案过时了吗?我看了一下变更日志,没有看到任何明显的变化。我认为这不太可能改变有很好的技术原因。你所说的“cdef类的cython数组”是什么意思?对于某些n
或Child*
,它是否对应于c++的Child a[n]
?显然,您的代码中存在一些问题(应该是self.array\u of_child
,应该为array\u of_child
分配内存,然后释放),因此解决这些问题可能会使您的目标更加清晰。
array_of_child = np.array([(Child() for i in range(100)])