我目前正在编写一个应该可以很好地扩展的应用程序,因此应该是模块化的。
为此,我使用抽象类/ mixins以及抽象方法来编写大多数模块。
我已经多次遇到以下问题:为了统一接口(ABC作为元数据库),我想声明抽象方法。我仍然想为其添加一些功能,以便实现可以调用super()来减少样板代码。通常这是用于前提条件检查。
具体来说,我有以下小例子:
class ProbabilisticBehaviour(AbstractBaseModel):
"""
Model supports probabilistic outputs
"""
def supports_probability_scores(self) -> True:
return True
@abstractmethod
def predict_probabilities(self, pool: AbstractPool) -> typing.List[typing.Tuple[ProbabilityNumber, ...]]:
"""
Will predict probabilities for each element
that is: This function is expected to deliver an list of tuples of length |unique_labels| where
sum(tuple) == 1 for each element in list (exclusive multiclass output)
:param pool:
:return:
"""
if not self.is_fitted() or not self.accepts_pool_for_prediction(pool) or not self.supports_probability_scores():
raise ModelPredictException("This model does not support prediction of "
"probabilities or preconditions"
"are not met (Not fitted? Data format does not match?) (Code: 28347234)")
# override
将其混合为类可以正常工作。调用super().predict_probabilities
也没有问题。尽管如此,这仍然让我感到自己并非那样。我的IDE(PyCharm)将抱怨函数主体中的return语句丢失。尽管如此,我还是想在此处声明返回类型以用于记录。另外,我见过的大多数抽象实现都是空(pass
)或只有raise NotImplementedError()
。
我也不想使用诸如really_predict_probabilities
之类的抽象函数来使实现混乱,该函数由当时非抽象的predict_probabilities
调用。
是否有一种“ Pythonic”的方式来做这些事情,还是我只能忍受呢?