Cython的`cdef`引发了一个NameError,其中`def`工作正常

时间:2014-05-14 15:13:18

标签: python cython

也许我错误地理解了cdef函数定义。例如,假设我想编写一个函数将Python列表转换为C数组:

%%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 个答案:

答案 0 :(得分:1)

引用docs,“cdef语句用于制作C级声明”

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

请注意,如果您计划在python代码中使用该函数,它将泄漏内存。您可能还想看看this答案,了解如何/为什么要将列表传入/从cython传递(免责声明:答案是我的)以避免泄漏。

编辑,回复更新的问题:

一旦引入cpdef,就会出现错误,因为指针无法以微不足道的方式转换为python对象。 Cython在最简单的情况下为您完成了艰苦的工作,请参阅here。你应该问这里的问题是为什么要返回一个指向python环境的C指针,它不提供指针。