简体   繁体   English

Python:调用继承父 Class 方法失败

[英]Python: Calling Inherited Parent Class Method Fails

I created a pass-through wrapper class around an existing class from sklearn and it does not behave as expected:我在来自sklearn的现有 class 周围创建了一个直通包装器 class ,但它的行为不符合预期:

import pandas as pd
from sklearn.preprocessing import OrdinalEncoder

tiny_df = pd.DataFrame({'x': ['a', 'b']})

class Foo(OrdinalEncoder):

    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)

    def fit(self, X, y=None):
        super().fit(X, y)
        return self


oe = OrdinalEncoder()
oe.fit(tiny_df) # works fine
foo = Foo()
foo.fit(tiny_df) # fails

The relevant part of the error message I receive is:我收到的错误消息的相关部分是:

~\.conda\envs\pytorch\lib\site-packages\sklearn\preprocessing\_encoders.py in _fit(self, X, handle_unknown)
     69                         raise ValueError("Unsorted categories are not "
     70                                          "supported for numerical categories")
---> 71             if len(self._categories) != n_features:
     72                 raise ValueError("Shape mismatch: if n_values is an array,"
     73                                  " it has to be of shape (n_features,).")

TypeError: object of type 'Foo' has no len()

Somehow parent's private property _categories does not seem to get set, even though I've called the parent constructor in the __init__() method of my class.尽管我在 class 的__init__()方法中调用了父构造函数,但似乎没有设置父级的私有属性_categories I must be missing something simple here, and would appreciate any help!我一定在这里遗漏了一些简单的东西,希望有任何帮助!

You don't have to pass self again to the super function.您不必再次将self传递给super function。 And scikit-learn 's estimators should always specify their parameters in the signature of their __init__ and no varargs are allowed else you will get a RUNTIMEERROR , so you have to remove it.并且scikit-learn的估算器应始终在其__init__的签名中指定其参数,并且不允许使用varargs ,否则您将获得RUNTIMEERROR ,因此您必须将其删除。 I have modified your code as below:我已将您的代码修改如下:

import pandas as pd
from sklearn.preprocessing import OrdinalEncoder

tiny_df = pd.DataFrame({'x': ['a', 'b']})

class Foo(OrdinalEncoder):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def fit(self, X, y=None):
        super().fit(X, y)
        return self


oe = OrdinalEncoder()
oe.fit(tiny_df) # works fine
foo = Foo()
foo.fit(tiny_df) # works fine too

SAMPLE OUTPUT样品 OUTPUT

foo.transform(tiny_df)
array([[0.],
       [1.]])

A little extra一点额外的

class Foo(OrdinalEncoder):

    def __init__(self, *args, **kwargs):
        super().__init__(*args,**kwargs)

    def fit(self, X, y=None):
        super().fit(X, y)
        return self

And when you create Foo :当您创建Foo时:

foo= Foo()

RuntimeError: scikit-learn estimators should always specify their parameters in the signature of their __init__ (no varargs). <class '__main__.Foo'> with constructor (self, *args, **kwargs) doesn't  follow this convention.

Hope it helps!希望能帮助到你!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM