Python setter without argument?

Viewed 2230

I'm using the property and setter decorators int he following way:

class PCAModel(object):
    def __init__(self):
        self.M_inv = None

    @property
    def M_inv(self):
        return self.__M_inv

    @M_inv.setter
    def set_M_inv(self):
        M = self.var * np.eye(self.W.shape[1]) + np.matmul(self.W.T, self.W)
        self.__M_inv = np.linalg.inv(M)

This generates an error in the __init__ function because my setter is not taking an argument:

TypeError: M_inv() takes 1 positional argument but 2 were given

I don't want to set the M_inv with an argument, since the calculations of M_inv rely solely on other properties of the class object. I could put a dummy argument in the setter:

@M_inv.setter
def set_M_inv(self, foo):
    M = self.var * np.eye(self.W.shape[1]) + np.matmul(self.W.T, self.W)
    self.__M_inv = np.linalg.inv(M)

but that feels dirty. Is there a better way to get around this?

1 Answers

You are missing the point of setters and getters, although the names are pretty self-explanatory. If your parameter is calculated independently from what you are trying to set (you want to ommit the argument in the setter), then a setter is just not needed at all. Since all you wanna do is calculate this parameter for each instance, just calculate and return the value in the getter, so you will be getting the correct, newly-calculated value each time you try to access your parameter.

    @property
    def M_inv(self):
        M = self.var * np.eye(self.W.shape[1]) + np.matmul(self.W.T, self.W)
        return np.linalg.inv(M)
Related