Ted Lilley wrote:
What I want to do is pre-load functions with arguments by iterating
through a list like so:


class myclass:

... pass

def func(self, arg):

... print arg

mylist = ["my", "sample", "list"]
for item in mylist:

... setattr(myclass, item, lamdba self: func(self, item))

This attaches a list of functions to the class, making them bound
methods when called from a class instance.


obj = myclass()
obj.list()

list Unfortunately, it doesn't work. It seems the closure keeps track of the variable fed to it dynamically - if the variable changes after the lambda is created, the lambda still references the _variable_ not the original _value_ and so gets the new value like so:


obj.sample()

list

obj.my()

list

The closure isn't bound until the scope containing it is exited. A simple workaround is to bind item as a default argument to the lambda:
for item in mylist:
setattr(myclass, item, lambda self, item=item: func(self, item))


You can also make a helper function that returns the closure, the closure will be bound each time the helper returns:

def make_f(item):
    def f(self): func(self, item)
    return f

mylist = ["my", "sample", "list"]
for item in mylist:
    setattr(myclass, item, make_f(item))

Kent
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to