Create properties using lambda getter and setter

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.

Answers


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 lambdas 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).

Edit: 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))

Need Your Help

Text not wrapping in p tag

html css twitter-bootstrap css3

I have two floated divs, side by side, with p tags inside. The text within the p tags does not wrap and just overflows the container, as you can see in the text under the images:

Java EE 6 vs. Spring 3 stack

java spring jsf java-ee java-ee-6

I'm starting a new project now. I have to choose technologies. I need something light, so no EJB or Seam. On the other hand I need JPA (Hibernate or alternative) and JSF with IceFaces.