I have something like this:
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)
Can I replace get_name
and set_name
using lambda functions?
I've tried this:
name = property(lambda self: self.__name, lambda self, value: self.__name = self.process_value(value))
but compiler doesn't like my setter function.
Accessor properties are represented by “getter” and “setter” methods. In an object literal they are denoted by get and set : let obj = { get propName() { // getter, the code executed on getting obj. propName }, set propName(value) { // setter, the code executed on setting obj.
A lambda function can take any number of arguments, but can only have one expression.
A lambda function can have any number of parameters, but the function body can only contain one expression.
@property is used to get the value of a private attribute without using any getter methods. We have to put a line @property in front of the method where we return the private variable. To set the value of the private variable, we use @method_name.
Your problem is that lambda's body must be an expression and assignment is a statement (a strong, deep distinction in Python). If you insist on perpetrating lambda
s you'll meet many such cases and learn the workarounds (there's usually one, though not always), such as, in this case:
name = property(lambda self: self.__name,
lambda self, value: setattr(self,
'_X__name',
self.process_value(value)))
i.e. use the built-in setattr
(which is a function and thus acceptable in a lambda
's body) rather than assignment (which is a statement and thus unacceptable in a lambda
's body).
You also need to perform the name-mangling for the dual-underscore attribute manually (changing __name
to _X__name
as you're in class X) where the attribute name is presented as a quoted string, as it must be in setattr
, as the Pyhon compiler only does the name mangling in question for suitable identifiers, not for string literals.
If you are extending a list
, you can also use __setitem__
, like this:
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))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With