2014-05-14 35 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

相關問題