Создайте свойства, используя лямбда-геттер и сеттер - PullRequest
6 голосов
/ 04 августа 2009

У меня есть что-то вроде этого:

class X():
    def __init__(self):
        self.__name = None

    def _process_value(self, value):
        # do something
        pass

    def get_name(self):
        return self.__name

    def set_name(self, value):
        self.__name = self._process_value(value)

    name = property(get_name, set_name)

Можно ли заменить get_name и set_name с помощью лямбда-функций?

Я пробовал это:

name = property(lambda self: self.__name, lambda self, value: self.__name = self.process_value(value))

но компилятору не нравится моя функция установки.

Ответы [ 2 ]

20 голосов
/ 04 августа 2009

Ваша проблема в том, что тело лямбды должно быть выражением, а присваивание - выражением (сильное глубокое различие в Python). Если вы настаиваете на совершении lambda s, вы встретите много таких случаев и узнаете обходные пути (обычно есть один, хотя и не всегда), например, в этом случае:

name = property(lambda self: self.__name, 
                lambda self, value: setattr(self, 
                                            '_X__name',
                                            self.process_value(value)))

т.е. используйте встроенный setattr (который является функцией и, следовательно, приемлемым в теле lambda), а не присваивание (которое является оператором и, следовательно, недопустимым в теле lambda).

Редактировать : Вам также необходимо вручную выполнить изменение имени для атрибута с двойным подчеркиванием (изменив значение __name на _X__name, когда вы находитесь в классе X), где представлено имя атрибута как строка в кавычках, как это должно быть в setattr, так как компилятор Pyhon делает искажение имени только для подходящих идентификаторов, а не для строковых литералов.

2 голосов
/ 08 декабря 2012

Если вы расширяете list, вы также можете использовать __setitem__, например:

class Position(list):
    def __init__(self,x=0, y=0, z=0):
        super(Position, self).__init__((x,y,z))

    x = property(lambda self: self[0],
                 lambda self,value: self.__setitem__(0, value))
    y = property(lambda self: self[1],
                 lambda self,value: self.__setitem__(1, value))
    z = property(lambda self: self[2],
                 lambda self,value: self.__setitem__(2, value))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...