Dynamic methods and lambda functions
Kay Schluehr
kay.schluehr at gmx.net
Sun Jan 25 06:03:05 EST 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