我有这样的事情:
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)
我可以使用lambda函数替换get_name
和set_name
吗?
我试过这个:
name = property(lambda self: self.__name, lambda self, value: self.__name = self.process_value(value))
但编译器不喜欢我的setter函数。
答案 0 :(得分:20)
你的问题是lambda的主体必须是一个表达式,赋值是一个声明(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编译器仅针对合适的标识符执行名称修改,而不是字符串文字。
答案 1 :(得分:2)
如果您要延长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))