There's probably a more generic mailing list I could send this to, but
I'm on too many lists as it is...hope y'all don't mind.

Anyway, I often find myself in the situation of "I have a list of
objects. I want to make a corresponding list of functions that operate
on those objects". So I write up something like this:

funcList = []
for item in objectList:
    funcList.append(lambda input: item.actOn(input))

But this doesn't work, because Python lazily binds the "item" variable
here. As a simple example:

>>> foo = [lambda: x + 2 for x in range(4)]
>>> [f() for f in foo]
[5, 5, 5, 5]

There's a workaround to force Python to make a copy of the variable
with its current value: use it as an optional argument to the lambda:

>>> foo = [lambda x = x: x + 2 for x in range(4)]
>>> [f() for f in foo]
[2, 3, 4, 5]

But that gets ugly fast if I have any level of nested loops involved
in my lambda creation. I had a situation yesterday in which I would
have had to have three variables bound using that method to keep
Python using the correct value of the variable: lambda a = a, b = b, c
= c: a.b(c). That sent me to the other workaround I know of, which is
to just define a new function that accepts the (three) inputs and
returns a lambda:

def makeFunc(a, b, c):
    return lambda: a.b(c)

This is still pretty painful though. Is there some way to get my
original example to work as it intuitively should? Or some equivalent
elegant alternative? That is, when a lambda is created, it should
include a closure of all scoped variables with their values as they
were at the time of creation of the lambda. Whereas right now as far
as I can tell it just includes references to those variables, and if
you should happen to change them between creating and calling the
lambda, then you're out of luck.

The actual use case I'm dealing with here is exposing various code
objects in a GUI; I need to create a button (or text field, or menu)
and then react to the user interacting with that object by calling a
function.

-Chris
_______________________________________________
Pythonmac-SIG maillist  -  Pythonmac-SIG@python.org
http://mail.python.org/mailman/listinfo/pythonmac-sig
unsubscribe: http://mail.python.org/mailman/options/Pythonmac-SIG

Reply via email to