Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Cython';s'cdef'会引发一个NameError,其中'def'可以正常工作_Python_Cython - Fatal编程技术网

Python Cython';s'cdef'会引发一个NameError,其中'def'可以正常工作

Python Cython';s'cdef'会引发一个NameError,其中'def'可以正常工作,python,cython,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

可能我对函数定义的
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
我得到一份工作

---------------------------------------------------------------------------
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
当我尝试使用
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
引用“cdef语句用于进行C级声明”

然后,如果向下滚动一点,就会看到不能从python调用
cdef
函数,因此会出现NameError。尝试使用
cpdef

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

编辑,回答更新的问题:


一旦引入
cpdef
就会发生错误,因为指针不能以简单的方式转换为python对象。Cython在最简单的情况下为您完成了艰巨的工作,请参见。这里您应该问的问题是,为什么要返回一个指向python环境的C指针,而该环境不提供指针。

谢谢,我有第二个函数
array\u to\u pythonlist
,它将通过
libc.stdlib.free(C\array)处理内存泄漏问题
但我没有提到它,因为它与问题的问题没有直接关系put cpdef:我以前尝试过,得到了一个
无法将“int*”转换为Python对象的问题,我将在上面的问题中发布完整的错误。非常感谢你的帮助!好啊但是,您将产生2个拷贝开销。如果你将一个numpy数组传递给cython,你不必复制到c分配的块中,我这样做的目的是将它与numpy数组方法进行比较(在基准测试方面)。当我使用numpy数组作为输入时,我注意到这种方法比使用C数组“慢”,如果您感兴趣,我这里有一个基准:我仍然不明白为什么您需要返回一个指向python的C指针。打开一个关于这两种方法性能的新问题,这个问题很有趣。我将尝试使用
xrange
而不是
range
,并尝试使用
cpdef
而不是
def
来声明两个测试
cython\u bubblesort\u clist
cython\u bubblesort\u numpy
。我认为你也应该尝试有效的索引。
%%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
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