Re: lambda closure question

From: Kent Johnson (kent37_at_tds.net)
Date: 02/19/05


Date: Sat, 19 Feb 2005 08:54:38 -0500

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



Relevant Pages

  • Re: defining classes-- different methods
    ... 'of the class' rather than 'of the class instance'. ... unique copy of the function object as one if its properties). ... for me if you're not going to make a closure. ... function declarations in the outer function. ...
    (comp.lang.javascript)
  • Re: Where does a class closure live?
    ... return Inner() ... closure variables for the class instance, ...
    (comp.lang.python)
  • Where does a class closure live?
    ... def outer: ... return Inner() ... Where are the closure variables for the class instance, ...
    (comp.lang.python)