Cython中出现错误消息“无法将'double *'转换为Python对象”

时间:2018-12-13 13:55:37

标签: python cython

此错误消息有很多问题,但是示例并非真的很少,所以...

当我对以下Cython模块进行Cython处理时

%%cython
cdef double *ptr=[1,2,3]
print(ptr)

我收到以下错误消息:

  

无法将'double *'转换为Python对象

但是,对于以下Cython模块:

%%cython
cdef double val=0.0
print(val)

被成功囊化了。

对于任何其他指针类型(即int *float *等),也会发生此问题。

1 个答案:

答案 0 :(得分:1)

print是一个纯Python函数,为了能够调用它,参数必须是Python对象。

很显然,第一个Cython模块中的ptr和第二个Cython模块中的val都不是python对象。但是有一个区别:cdef类型的double变量可以由Cython通过PyFloat_FromDouble自动转换为Python-Float-这正是在后台进行的:Cython创建来自val的临时Python-Float,将其传递到print,然后销毁。

还有其他可以自动转换为Python对象的类型:doublefloatint和类似的对象,但也有std::vector and other c++-containers

但是,对于原始C指针并没有这种自动转换-因为首先无法进行转换,因为Cython不知道数组的长度(根本就是数组吗?)指针指向的位置。

在这种情况下,唯一的解决方案:必须手动将内存内容转换为python列表(或其对应的任何python类型),例如函数convert_to_python

%%cython 
cdef convert_to_python(double *ptr, int n):
    cdef int i
    lst=[]
    for i in range(n):
        lst.append(ptr[i])
    return lst

cdef double *ptr=[1,2,3]
print(convert_to_python(ptr,3))

最值得注意的是,convert_to_python将元素数作为参数-信息Cython丢失。

顺便说一句:Cython会将具有已知长度的C数组自动转换为Python对象,例如:

%%cython 
cdef double arr[3] # length (=3) known to Cython 
arr[:]=[1,2,3]
print(arr)

编译没有问题。