__在扩展Cython类时,cinit_uu4()只接受2个位置参数

2024-04-29 03:33:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我想扩展scikitlearn的ClassificationCriterion类,它被定义为内部模块^{}中的Cython类。我希望在Python中这样做,因为通常我不能访问sklearn的pyx/pxd文件(因此我不能cimport它们)。但是,当我试图扩展ClassificationCriterion时,我得到了错误TypeError: __cinit__() takes exactly 2 positional arguments (0 given)。下面的MWE再现了错误,并显示错误发生在__new__之后,__init__之前。在

有没有办法像这样扩展Cython类?在

from sklearn.tree import DecisionTreeClassifier
from sklearn.tree._criterion import ClassificationCriterion

class MaxChildPrecision(ClassificationCriterion):
    def __new__(self, *args, **kwargs):
        print('new')
        super().__new__(MaxChildPrecision, *args, **kwargs)

    def __init__(self, *args, **kwargs):
        print('init')
        super(MaxChildPrecision).__init__(*args, **kwargs)

clf = DecisionTreeClassifier(criterion=MaxChildPrecision())

Tags: fromimporttreenewinitdef错误args
1条回答
网友
1楼 · 发布于 2024-04-29 03:33:52

有两个问题。首先,^{} requires two specific arguments to its constructor that you aren't passing it。您必须计算出这些参数代表什么并将它们传递给基类。在

其次,还有一个赛顿问题。如果我们看the description of how to use ^{},那么我们会看到:

Any arguments passed to the constructor will be passed to both the __cinit__() method and the __init__() method. If you anticipate subclassing your extension type in Python, you may find it useful to give the __cinit__() method * and ** arguments so that it can accept and ignore extra arguments. Otherwise, any Python subclass which has an init() with a different signature will have to override __new__() as well as __init__()

不幸的是,sklearn的编写者没有提供*和{}参数,因此必须重写{}。这样的方法应该有效:

class MaxChildPrecision(ClassificationCriterion):
    def __init__(self,*args, **kwargs):
        pass

    def __new__(cls,*args,**kwargs):
        # I have NO IDEA if these arguments make sense!
        return super().__new__(cls,n_outputs=5,
                           n_classes=np.ones((2,),dtype=np.int))

我将必要的参数传递给__new__中的ClassificationCriterion,并在{}中处理其余参数。我不需要调用基类__init__(因为基类没有定义__init__)。在

相关问题 更多 >