mardi 4 octobre 2016

Only recalculate derived attributes when necessary

I currently have code that looks something like this

class Model(object):
    """An object that models some physical phenomenon"""
    def __init__(self, attr1, attr2):
        """Initialize the model attributes"""
        self._attr1 = attr1
        self._attr2 = attr2
        self._attr_changed()

    def _attr_changed():
        """Change internal state so that derived attributes are recalculated"""
        self._derived1 = None
        self._derived2 = None

    @property
    def attr1(self):
        return self._attr1

    @attr1.setter
    def attr1(self, value):
        self._attr_changed()
        self._attr2 = value

    @property
    def attr2(self):
        return self._attr2

    @attr2.setter
    def attr2(self, value):
        self._attr_changed()
        self._attr2 = value

    @property
    def derived1(self):
        if self._derived1 is None:
            self._derived1 = self.attr1 + self.attr2
        return self._derived1

    @property
    def derived2(self):
        if self._derived2 is None:
            self._derived2 = self.derived1 * self.attr1 * self.attr2
        return self._derived2

The idea is that the model will only calculate the derived properties when needed and store them otherwise. Its like memoization but only caching the last result.

There must be a better (more pythonic) way to do this which is cleaner and less error prone but my googling has yet to turn up anything useful.

Aucun commentaire:

Enregistrer un commentaire