2014-05-14 123 views
-1

也许我正确理解cdef错误地定义了函数定义。例如,假设我想编写一个函数到Python的列表转换为C数组:Cython的`cdef`引发了一个NameError,其中`def`正常工作

%%cython 
cimport cython 
from libc.stdlib cimport malloc, free 
cdef int* list_to_array(a_list): 
    """ Converts a Python list into a C array """ 
    cdef int *c_array 
    cdef int count, n 
    c_array = <int *>malloc(len(a_list)*cython.sizeof(int)) 
    count = len(a_list) 
    for i in range(count): 
     c_array[i] = a_list[i] 
    return c_array 

,当我通过

list_to_array([1,2,3]) 

现在所说的功能,我收到了

--------------------------------------------------------------------------- 
NameError         Traceback (most recent call last) 
<ipython-input-32-8f3f777d7883> in <module>() 
----> 1 list_to_array([1,2,3]) 

NameError: name 'list_to_array' is not defined 

但是,当我使用def时,可以调用该函数(虽然它不会返回我想要的内容,但它仅用于说明我的问题......)

%%cython 
cimport cython 
from libc.stdlib cimport malloc, free 
def list_to_array1(a_list): 
    """ Converts a Python list into a C array """ 
    cdef int *c_array 
    cdef int count, n 
    c_array = <int *>malloc(len(a_list)*cython.sizeof(int)) 
    count = len(a_list) 
    for i in range(count): 
     c_array[i] = a_list[i] 
    return 1 


list_to_array1([1,2,3]) 

1 

当我试图用cpdef而不是cdef,我遇到一个不同的问题:

Error compiling Cython file: 
------------------------------------------------------------ 
... 
cimport cython 
from libc.stdlib cimport malloc, free 
cpdef int* list_to_carray(a_list): 
    ^
------------------------------------------------------------ 

/Users/sebastian/.ipython/cython/_cython_magic_c979dc7a52cdfb492e901a4b337ed2d2.pyx:3:6: Cannot convert 'int *' to Python object 

回答

1

援引docs说:“cdef语句用来使C级声明”

然后,如果你向下滚动一下here,你会发现cdef函数不能从python调用,因此你的NameError。尝试使用cpdef

请注意,如果您打算在python代码中使用该函数,它会泄漏内存。您可能还想看看this回答如何/为什么你应该返回从cython传递一个列表(免责声明:答案是我的),以避免泄漏。

编辑,在回答更新问题:

的错误,一旦你介绍cpdef是因为指针不能在平凡的方式转换为Python对象。 Cython在最简单的情况下为您做了很多努力,请参阅here。你应该问这里的问题是为什么你要返回一个指向Python环境的C指针,它不提供指针。

+0

谢谢,我有第二个函数'array_to_pythonlist',通过'libc.stdlib.free(c_array)'来处理内存泄漏,但我没有提及它,因为它不直接关系到问题 – Sebastian

+0

Abp cpdef:我之前尝试过,并得到'不能将'int *'转换为Python对象',我会在上面的问题中发布完整的错误。非常感谢你的帮助! – Sebastian

+0

好的。然而,你是在​​2副本开销。如果你传递给cython一个numpy数组,你不必复制到/从一个c分配的块。 – gg349

相关问题