首页 > 解决方案 > Cython-C 方法之前未在扩展类型的定义部分中声明

问题描述

我正在做一个需要这个库(pylibol)的项目。链接: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。

标签: pythonpython-2.7cythoncythonize

解决方案


最简单的方法可能是回到 2017 版本的 Cython。看起来它最初是用 Cython 0.25.2 内置的。


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

cdef get_weight

表示该类有一个名为的属性,该属性get_weight被键入为 Python 对象(默认情况下)。相反,你想匹配的函数签名get_weight

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

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


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


推荐阅读