0

I am currently writing an application that should be esily extensible, hence should be modular.

For that I write most of the modules using abstract classes / mixins, alongside with abstract methods.

Multiple times already I was facing the following question: I want to declare abstract methods for the purpose of uniform interfaces (ABC as meta base). Still I want to add some functionality to it so the implementation may call super() to reduce boilerplate code. Mostly this is for precondition checks.

Concretely I have following small example:

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

Mixing this into a class works fine. Calling super().predict_probabilities also works with no problems. Still, it leaves me with the feeling that this is not meant to be like that. My IDE (PyCharm) will complain for missing return statement in the function body. Still, I want to declare the return types there for documentation purposes. In addition, most implementations of abstracts I have seen are empty (pass) or only raise NotImplementedError(). I also don't want to clutter the implementation with some abstract function like really_predict_probabilities which is called by the then-non-abstract predict_probabilities.

Is there a "Pythonic" way to do such things or do I just have to life with that?

Ric Hard
  • 599
  • 4
  • 12
  • This way you can't actually require that the implementing classes *do* call the `super` method. Similar question from yesterday: https://stackoverflow.com/q/55025518/3001761 – jonrsharpe Mar 07 '19 at 11:51
  • Thanks for the very fast reply. Im aware that I cannot force to call super but only to implement the method. The implementation is merely an offer that is valid for most cases. If the actual Model wants to do stomething else, thats fine as long as it conforms to the interface. It just feels like "could be done more clean". But I think this would involve adding an additional method that is containing the actual function body, which I personally see as unwanted clutter. I think I live with what it is now, if there is no "better" way doing that. – Ric Hard Mar 07 '19 at 12:00

0 Answers0