Python中不带参数的setter方法?

3

我正在以下方式使用属性和 setter 装饰器:

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)

这会在__init__函数中产生一个错误,因为我的setter没有接受参数:

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

我不想通过参数来设置 M_inv,因为计算 M_inv 只依赖于类对象的其他属性。我可以在 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)

但这样做感觉很不好。有没有更好的方法来解决这个问题呢?
1个回答

2

你似乎没有理解setters和getters的意义,尽管它们的名称已经很容易理解了。如果你的参数是独立于你要设置的内容计算出来的(你想在setter中省略参数),那么根本不需要使用setter。因为你想要做的就是为每个实例计算这个参数,只需在getter中计算并返回该值,这样每次访问参数时就可以获取正确的、新计算的值。

    @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)

1
谢谢。问题在于我想要一个getter来获取当前值,然后再有一个函数来单独更新该值。这样我就可以在更新M_inv并获取“新”值之前获取“旧”值。也许只需要一个getter,然后有一个简单的函数update_M_inv就可以了?或者甚至不需要getter,因为我们不需要对属性进行任何预处理? - Sahand
1
在这种情况下,我认为你采用更新函数的方法是以面向对象的符合方式解决问题的最佳途径! - felipecgonc
1
@Sahand 为什么不直接删除 @M_inv.setter 装饰器,使 "calculate" 方法与 getter 方法同名但没有参数。这样做不太好看,但函数命名取决于您... - R Yoda

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接