Dynamic methods and lambda functions

Kay Schluehr kay.schluehr at gmx.net
Sun Jan 25 12:03:05 CET 2009


On 23 Jan., 13:28, unine... at gmail.com wrote:
> Hi,
> I want to add some properties dynamically to a class, and then add the
> corresponding getter methods. Something resulting in this:
>
> class Person:
>     def Getname(self):
>         return self.__name
>
>     def Getage(self):
>         return self.__age
>
> I've implemented the next code, creating the properties from a list:
>
> props = [
>     ("name", "peter"),
>     ("age", 31),
>     ("wife", "mary")
>     ]
>
> class Person:
>     def __init__(self):
>         for prop in props:
>             setattr(self, "__" + prop[0], prop[1])
>             setattr(Person, "Get" + prop[0], lambda self: getattr
> (self, "__" + prop[0]))
>
> if __name__ == "__main__":
>
>     person = Person()
>
>     print person.__name
>     print person.__age
>     print person.__wife
>     print
>     print person.Getname()
>     print person.Getage()
>     print person.Getwife()
>
> And the resulting execution of this program is:
>
> peter
> 31
> mary
>
> mary
> mary
> mary
>
> The attributes are right, but the getter are not working. The problem
> is that the lambda function always execute the last parameter passed
> for all instances of the methods. How could it be done the right way?
>
> Thanks in advance

The standard trick is to "de-closure" the lambda using a keyword
argument. So instead of writing

   lambda self: getattr(self, "__" + prop[0]))

you might write

   lambda self, prop = prop: getattr(self, "__" + prop[0]))

Now prop is local to the lambda and the lambda doesn't look up prop in
the enclosing environment which certainly stores its last value.



More information about the Python-list mailing list