代码之家  ›  专栏  ›  技术社区  ›  tefozi

使用lambda getter和setter创建属性

  •  5
  • tefozi  · 技术社区  · 17 年前

    我有这样的东西:

    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 使用lambda函数?

    我试过了:

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

    但编译器不喜欢我的setter函数。

    2 回复  |  直到 13 年前
        1
  •  19
  •   Alex Martelli    17 年前

    您的问题是lambda的主体必须是一个表达式,而赋值则是一个语句(在python中是一个很强、很深的区别)。如果你坚持犯罪 lambda 你会遇到许多这样的情况并学习解决方法(通常有一个,但并不总是如此),例如,在这种情况下:

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

    即使用内置的 setattr (这是一个函数,因此在 兰姆达 而不是转让(这是一种声明,因此在 兰姆达 的身体)。

    编辑 :您还需要手动执行双下划线属性的名称管理(更改 __name 到 _X__name 正如您在类x)中一样,属性名以带引号的字符串表示,正如它必须在setattr中一样,因为pyhon编译器只对合适的标识符(而不是字符串文本)进行有疑问的名称管理。

        2
  •  2
  •   Philipp Kewisch    13 年前

    如果您要扩展 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))