如何在Python中正确重写和调用super方法
首先是眼前的问题。我正在为一个如何在Python中正确重写和调用super方法,python,scikit-learn,classification,text-classification,Python,Scikit Learn,Classification,Text Classification,首先是眼前的问题。我正在为一个scikitlearn类编写一个包装器,但在正确的语法方面遇到了问题。我试图实现的是对fit_transform函数的覆盖,该函数仅稍微改变输入,然后使用新参数调用其super-方法: from sklearn.feature_extraction.text import TfidfVectorizer class TidfVectorizerWrapper(TfidfVectorizer): def __init__(self): Tfi
scikitlearn
类编写一个包装器,但在正确的语法方面遇到了问题。我试图实现的是对fit_transform
函数的覆盖,该函数仅稍微改变输入,然后使用新参数调用其super
-方法:
from sklearn.feature_extraction.text import TfidfVectorizer
class TidfVectorizerWrapper(TfidfVectorizer):
def __init__(self):
TfidfVectorizer.__init__(self) # is this even necessary?
def fit_transform(self, x, y=None, **fit_params):
x = [content.split('\t')[0] for content in x] # filtering the input
return TfidfVectorizer.fit_transform(self, x, y, fit_params)
# this is the critical part, my IDE tells me for
# fit_params: 'unexpected arguments'
程序到处崩溃,从一个多处理异常开始
,没有告诉我任何有用的信息。如何正确地执行此操作
其他信息:我需要以这种方式包装它的原因是,我使用sklearn.pipeline.FeatureUnion
收集我的功能提取器,然后将它们放入sklearn.pipeline.pipeline
。这样做的结果是,我只能在所有特性提取器中提供单个数据集,但不同的提取器需要不同的数据。我的解决方案是以易于分离的格式提供数据,并在不同的提取器中过滤不同的部分。如果有更好的办法解决这个问题,我也很高兴听到
编辑1:
添加**
来解压dict似乎不会改变任何东西:
编辑2:
我刚刚解决了剩下的问题--我需要删除构造函数重载。显然,通过尝试调用父构造函数,希望正确启动所有实例变量,我做了完全相反的事情。我的包装器不知道它可以期望什么样的参数。一旦我删除了多余的调用,一切都很顺利。您忘记了解包
fit_params
,它是作为dict
传递的,您想作为关键字参数来传递它,它需要解包操作符**
from sklearn.feature_extraction.text import TfidfVectorizer
class TidfVectorizerWrapper(TfidfVectorizer):
def fit_transform(self, x, y=None, **fit_params):
x = [content.split('\t')[0] for content in x] # filtering the input
return TfidfVectorizer.fit_transform(self, x, y, **fit_params)
另一件事是直接调用TfidfVectorizer
的fit_transform
可以通过super
方法调用重载版本
from sklearn.feature_extraction.text import TfidfVectorizer
class TidfVectorizerWrapper(TfidfVectorizer):
def fit_transform(self, x, y=None, **fit_params):
x = [content.split('\t')[0] for content in x] # filtering the input
return super(TidfVectorizerWrapper, self).fit_transform(x, y, **fit_params)
要理解它,请检查以下示例
def foo1(**kargs):
print kargs
def foo2(**kargs):
foo1(**kargs)
print 'foo2'
def foo3(**kargs):
foo1(kargs)
print 'foo3'
foo1(a=1, b=2)
它打印字典{'a':1,'b':2}
foo2(a=1, b=2)
打印字典和foo2
,但
foo3(a=1, b=2)
当我们向foo1
发送一个与我们的字典相等的位置参数时引发错误,该参数不接受此类内容。不过,我们可以这样做
def foo4(**kargs):
foo1(x=kargs)
print 'foo4'
这很好,但是打印了一个新字典{'x':{'a':1,'b':2}
是否尝试将返回TfidfVectorizer.fit_transform(self,x,y,fit_参数)
替换为返回TfidfVectorizer.fit_transform(self,x,y,**fit_参数)
?还取决于y
在方法签名中的位置,可能需要“命名”y
:返回TfidfVectorizer.fit\u transform(self,x,y=y,**fit\u参数)
@klauds。同意,但fit_params几乎肯定不是传递的正确内容,因为它是一个字典。我现在尝试了这两种方法,添加了**fit_params
,但没有改变任何内容,在尝试时仍然会出现完全相同的IDE警告和运行时异常。添加y=y会出现语法错误,因为fit_参数是在关键字之后输入的。改变它会产生另一个语法错误。可能值得添加一两个关于super()
的单词来回答其他问题。我尝试了你的建议,但仍然收到完全相同的错误。我也在主要帖子中添加了一条评论。我确实有意删除了构造函数,也许它应该加下划线