python - setters - poo getter setter
Crear propiedades usando lambda getter y setter (2)
Tengo algo como esto:
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)
¿Puedo reemplazar get_name
y set_name
usando las funciones lambda?
He intentado esto:
name = property(lambda self: self.__name, lambda self, value: self.__name = self.process_value(value))
pero al compilador no le gusta mi función setter.
Tu problema es que el cuerpo de lambda debe ser una expresión y la asignación es una afirmación (una distinción fuerte y profunda en Python). Si insiste en perpetrar lambda
, encontrará muchos de estos casos y aprenderá las soluciones (generalmente hay una, aunque no siempre), como en este caso:
name = property(lambda self: self.__name,
lambda self, value: setattr(self,
''_X__name'',
self.process_value(value)))
es decir, use el setattr
(que es una función y, por lo tanto, aceptable en lambda
cuerpo de una lambda
) en lugar de la asignación (que es una afirmación y, por lo tanto, inaceptable en lambda
cuerpo de una lambda
).
Editar : también es necesario realizar manualmente el cambio de nombre para el atributo dual-underscore (cambiando __name
a _X__name
como está en la clase X) donde el nombre del atributo se presenta como una cadena entre comillas, como debe ser en setattr, como el compilador de Pyhon solo hace que el nombre cambie en cuestión para identificadores adecuados, no para literales de cadenas.
Si extiende una list
, también puede usar __setitem__
, de esta manera:
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))