Как использовать свойства и сеттеры по Pythonic - PullRequest
0 голосов
/ 08 января 2019

Я следую этому примеру кода из курса Python :

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)

Обратите внимание, что я хочу, чтобы свойство M_inv было None до того, как я запустил сеттер в первый раз. Кроме того, установщик полагается исключительно на другие свойства объекта класса, а не на входные аргументы.

Сеттер-декоратор генерирует ошибку:

NameError: name 'M_inv' is not defined

Почему это?

Ответы [ 2 ]

0 голосов
/ 08 января 2019

Пример неверный.

РЕДАКТИРОВАТЬ: В примере был специально использован сеттер в __init__.

Получатели и установщики, даже если они действуют как свойства, являются всего лишь методами, которые обращаются к закрытому атрибуту. Этот атрибут должен существовать . В этом примере 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)
0 голосов
/ 08 января 2019

Ваш метод установки должен быть таким, как показано ниже:

@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): должны совпадать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...