如何在 Python 中正确覆盖和调用超级方法
How to correctly override and call super-method in Python
首先,手头的问题。我正在为 scikit-learn
class 编写一个包装器,并且在使用正确的语法时遇到了问题。我想要实现的是重写 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'
程序到处崩溃,从 Multiprocessing exception
开始,并没有真正告诉我任何有用的信息。我该如何正确执行此操作?
附加信息:我需要这样包装的原因是因为我使用 sklearn.pipeline.FeatureUnion
来收集我的特征提取器,然后再将它们放入 sklearn.pipeline.Pipeline
。这样做的结果是,我只能在所有特征提取器中提供一个数据集——但不同的提取器需要不同的数据。我的解决方案是以易于分离的格式提供数据,并在不同的提取器中过滤不同的部分。如果这个问题有更好的解决方案,我也很乐意听到。
编辑 1:
添加 **
解压字典似乎没有改变任何东西:
编辑 2:
我刚刚解决了剩下的问题——我需要删除构造函数重载。显然,通过尝试调用父构造函数,希望正确启动所有实例变量,我做了完全相反的事情。我的包装器不知道它可以期望什么样的参数。一旦我删除了多余的调用,一切就完美了。
您忘记解压作为 dict
传递的 fit_params
,而您想将其作为 keyword arguments
传递,这需要解包运算符 **
。
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}}
首先,手头的问题。我正在为 scikit-learn
class 编写一个包装器,并且在使用正确的语法时遇到了问题。我想要实现的是重写 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'
程序到处崩溃,从 Multiprocessing exception
开始,并没有真正告诉我任何有用的信息。我该如何正确执行此操作?
附加信息:我需要这样包装的原因是因为我使用 sklearn.pipeline.FeatureUnion
来收集我的特征提取器,然后再将它们放入 sklearn.pipeline.Pipeline
。这样做的结果是,我只能在所有特征提取器中提供一个数据集——但不同的提取器需要不同的数据。我的解决方案是以易于分离的格式提供数据,并在不同的提取器中过滤不同的部分。如果这个问题有更好的解决方案,我也很乐意听到。
编辑 1:
添加 **
解压字典似乎没有改变任何东西:
编辑 2: 我刚刚解决了剩下的问题——我需要删除构造函数重载。显然,通过尝试调用父构造函数,希望正确启动所有实例变量,我做了完全相反的事情。我的包装器不知道它可以期望什么样的参数。一旦我删除了多余的调用,一切就完美了。
您忘记解压作为 dict
传递的 fit_params
,而您想将其作为 keyword arguments
传递,这需要解包运算符 **
。
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}}