Maltergate
Maltergate

Reputation: 79

Best way to implement a method specific to a class but does not directrly uses the attributes

I have a class which stores data and allows me to update it given some measurements. However, the update step does not take directly the attribute as is, but a modified version. Same goes with the output of my update: I still have to process it before saving it into the object attribute.

class Dummy:
    def _prepare_data(self):
        X = self.X
        # Do stuff to X
        return X_prepared
   
    @staticmethod
    def _update(X_prep, measures):
        # Do stuff to X_prep with measures
        return X_updated

    def _store_result(self, X_up):
        # Do stuff to X_up
        self.X = X_up_good_format

    def do_update(self, measures):
        # Method called from the outside, user doesn't care about data prep
        X = self._prepare_data()
        X = self._update(X, measures)
        self._store_results(X)

In this case, my private method _update is blind to the class as I don't need nor attributes or methods of my class, but it doesn't make sense for me to put it as a simple function outside because it doesn't "live on its own", it only exists to be used in this class. I've therefore put the method as a static method (as in the example) but I've read that doing so was a sign of bad design because it goes against OOP paradigm. Is there a better way to do this?

PS: I'd rather not merge the three private methods because I want to be able to call the method _update independently for testing purposes.

Upvotes: 2

Views: 59

Answers (1)

Mad Physicist
Mad Physicist

Reputation: 114320

The way I would address your concern is to merge _update with do_update into one, and make _prepare_data and _store_result into a single property:

class Dummy:
    @property
    def X(self):
        X = self._X
        # Do stuff to X
        return X_prepared

    @X.setter
    def X(self, value):
        # Do stuff to value
        self._X = value_good_format

    def do_update(self, measures):
        # Method called from the outside, user doesn't care about data prep
        # Do stuff to self.X with measures
        self.X = X_updated

Now child classes can override just the do_update method, while still relying on the conversions provided by the property X.

Upvotes: 2

Related Questions