python-3.x - Pythonic 减少子类的方法
问题描述
背景:所以,我正在研究一个 NLP 问题。我需要根据不同类型的文本文档提取不同类型的特征。我目前有一个设置,其中有一个 FeatureExtractor 基类,它根据不同类型的文档被多次子类化,所有这些都计算一组不同的特征并返回一个熊猫数据框作为输出。
所有这些子类都由一个名为 FeatureExtractionRunner 的包装类型类进一步调用,该类调用所有子类并计算所有文档的特征并返回所有类型文档的输出。
问题:这种计算特征的模式会导致很多子类。目前,我有 14 个子类,因为我有 14 种类型的文档。它可能会进一步扩展。而且要维护的课程太多了。有没有其他方法可以做到这一点?子类化较少
这是我解释的一些示例代表性代码:
from abc import ABCMeta, abstractmethod
class FeatureExtractor(metaclass=ABCMeta):
#base feature extractor class
def __init__(self, document):
self.document = document
@abstractmethod
def doc_to_features(self):
return NotImplemented
class ExtractorTypeA(FeatureExtractor):
#do some feature calculations.....
def _calculate_shape_features(self):
return None
def _calculate_size_features(self):
return None
def doc_to_features(self):
#calls all the fancy feature calculation methods like
f1 = self._calculate_shape_features(self.document)
f2 = self._calculate_size_features(self.document)
#do some calculations on the document and return a pandas dataframe by merging them (merge f1, f2....etc)
data = "dataframe-1"
return data
class ExtractorTypeB(FeatureExtractor):
#do some feature calculations.....
def _calculate_some_fancy_features(self):
return None
def _calculate_some_more_fancy_features(self):
return None
def doc_to_features(self):
#calls all the fancy feature calculation methods
f1 = self._calculate_some_fancy_features(self.document)
f2 = self._calculate_some_more_fancy_features(self.document)
#do some calculations on the document and return a pandas dataframe (merge f1, f2 etc)
data = "dataframe-2"
return data
class ExtractorTypeC(FeatureExtractor):
#do some feature calculations.....
def doc_to_features(self):
#do some calculations on the document and return a pandas dataframe
data = "dataframe-3"
return data
class FeatureExtractionRunner:
#a class to call all types of feature extractors
def __init__(self, document, *args, **kwargs):
self.document = document
self.type_a = ExtractorTypeA(self.document)
self.type_b = ExtractorTypeB(self.document)
self.type_c = ExtractorTypeC(self.document)
#more of these extractors would be there
def call_all_type_of_extractors(self):
type_a_features = self.type_a.doc_to_features()
type_b_features = self.type_b.doc_to_features()
type_c_features = self.type_c.doc_to_features()
#more such extractors would be there....
return [type_a_features, type_b_features, type_c_features]
all_type_of_features = FeatureExtractionRunner("some document").call_all_type_of_extractors()
解决方案
__init__
首先回答这个问题,您可能会以每次都编写方法为代价来完全避免子类化。或者您可以完全摆脱这些类并将它们转换为一堆函数。甚至您可以将所有课程加入一个课程。请注意,这些方法都不会使代码更简单或更易于维护,实际上它们只会在某种程度上改变它的形状。
恕我直言,这种情况是固有问题复杂性的一个完美例子,我的意思是域(NLP)和特定用例(文档特征提取)本身就是复杂的。
例如,featureX和featureY可能是完全不同的东西,无法完全计算,因此您最终只能使用一种方法。同样,在数据框中合并这些特征的过程可能与合并花哨的特征的过程不同。在这种情况下拥有很多函数/类对我来说似乎是完全合理的,将它们分开也是合乎逻辑和可维护的明智之举。
也就是说,如果您可以将一些代码组合成一个更通用的函数,那么真正的代码减少可能feature calculation methods
是可能的,但我不能确定它是否可能。
推荐阅读
- sql-server - 在 TSQL 中导入或转换使用时区数据扩展的 ISO 8601 日期
- go - 如何使用反射在 Go 中找到空的结构值?
- javascript - require.resolve 找不到文件,即使 fs 可以
- javascript - 如何使用 async/await 进行错误处理而无需等待
- macos - 有没有办法为 MacOs Mojave 中的单个应用程序打开/关闭暗模式?
- java - 查找句子中的元音和辅音的程序
- javascript - React Native - Android - 全局禁用后退按钮的问题
- swift - 替换subscriberCellularProviderDidUpdate
- xamarin - Xamarin Forms iOS TitleBarTextColor 没有改变
- python - Python函数工作得很好,但在for循环时不起作用