如何使用属性和设置器以Python方式

时间:2019-01-08 13:38:04

标签: python properties

我正在遵循python course中的以下代码示例:

class P:

    def __init__(self,x):
        self.x = x

    @property
    def x(self):
        return self.__x

    @x.setter
    def x(self, x):
        if x < 0:
            self.__x = 0
        elif x > 1000:
            self.__x = 1000
        else:
            self.__x = x

然后我尝试将这种模式实现到我自己的代码中:

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)

请注意,在我第一次运行setter之前,我希望M_inv属性为None。此外,设置器仅依赖于类对象的其他属性,而不依赖于输入参数。

setter装饰器生成错误:

NameError: name 'M_inv' is not defined

这是为什么?

2 个答案:

答案 0 :(得分:1)

您的设置方法应如下所示:

@M_inv.setter
def 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)

修饰器@M_inv.setter和函数def M_inv(self):的名称应该相同

答案 1 :(得分:0)

该示例是错误的。

编辑:示例是故意在__init__中使用setter。

字母和setter,即使它们的行为类似于属性,也只是访问私有属性的方法。该属性必须存在。 在此示例中,从未创建self.__x

这是我建议的用途:

class PCAModel(object):
    def __init__(self):
        # We create a private variable
        self.__M_inv = None

    @property
    def M_inv(self):
        # Accessing M_inv returns the value of the previously created variable
        return self.__M_inv

    @M_inv.setter
    def M_inv(self):  # Keep the same name than your propery
        M = self.var * np.eye(self.W.shape[1]) + np.matmul(self.W.T, self.W)
        self.__M_inv = np.linalg.inv(M)