先前未在扩展类型的定义部分中声明的 Cython- C 方法

Cython- C method not previously declared in definition part of extension type

我正在做一个需要这个库(pylibol)的项目。 link:https://github.com/billhhh/pylibol。当我构建 setup.py 时,它显示 C 方法 'get_weight' 之前未在扩展类型 'SOL'.

的定义部分中声明
> Error compiling Cython file:
> ------------------------------------------------------------ ...
>         dict: mapping of string to string
>         """
>         params = dict()
>         sol_GetModelParameters(self._c_model, get_parameter, <void*>params)
>         return params
>     cpdef np.ndarray[float, ndim=1, mode="c"] get_weight(self, cls_id=0):
>          ^
> ------------------------------------------------------------
> 
> python/pysol.pyx:141:10: C method 'get_weight' not previously declared
> in definition part of extension type 'SOL'

问题发生在pysol.pyx。所以我检查了 pysol.pyx 并在 pysol.pdx.

中添加了 cdef get_weight

pysol.pyx:

def get_params(self):
        """Get Model Parameters

        Returns
        -------
        dict: mapping of string to string
        """
        params = dict()
        sol_GetModelParameters(self._c_model, get_parameter, <void*>params)
        return params
    cpdef np.ndarray[float, ndim=1, mode="c"] get_weight(self, cls_id=0):
        """Get Model Weight,
        input cls_id: the id of classifier, in range 0 to cls_num-1
        output an numpy array of classifier for the cls_id 's class.
        for binary classifier, cls_id is 0 and cls_num=1
        """
        d=sol_Getw_dime(self._c_model, cls_id)
        cdef np.ndarray[float, ndim=1, mode="c"] w = np.zeros((d,),dtype=np.float32)
        sol_Getw(self._c_model, cls_id,&w[0])
        return w

pysol.pdx:

cdef class SOL:
    cdef void* _c_model
    cdef void* _c_data_iter
    cdef const char* algo
    cdef int class_num
    cdef bint verbose
    cdef get_weight

但这件事发生了:

AttributeError: 'PyObjectType' 对象没有属性 'exception_check'

知道为什么会这样吗? 我正在研究 ubuntu 并使用 python 2.7.

最简单的方法可能是回到 2017 版的 Cython。它 looks like 它最初是用 Cython 0.25.2 内置的。


如果您不想这样做,那么您需要查看要添加的行:

cdef get_weight

表示 class 有一个名为 get_weight 的属性,它被类型化为 Python 对象(默认情况下)。相反,您想匹配 get_weight

的函数签名
cpdef np.ndarray[float, ndim=1, mode="c"] get_weight(self, cls_id=0)

(我不记得你对默认参数做了什么 - 你可能需要从 .pyx 文件中删除 =0)。


或者,您可以将“.pyx”文件中的 cpdef 更改为 defdef 函数不需要提前声明(在我看来 cpdef 函数通常是错误的选择)。