newbie with major "lambda" problem (perhaps a scope problem as well)

John Roth johnroth at ameritech.net
Wed Jun 27 01:00:52 EDT 2001


"Joe Potter" <jm7potter at hotmail.com> wrote in message
news:n8dhjt8qmel0ajjae7tv9gmjf60c39qag5 at 4ax.com...
> On Tue, 26 Jun 2001 16:09:06 GMT, "Rainer Deyke" <root at rainerdeyke.com>
wrote:
>
> >"Joe Potter" <jm7potter at hotmail.com> wrote in message
> >news:j5ahjtkfmf32lkqtap0q1u6rig385d7b5i at 4ax.com...
> >>     # the "button" below works like a champ !!
> >>     #Button(root, text='Fetch',
> >>                  #command=(lambda v=vars: fetch(v))).pack(side=LEFT)
> >>
> >>     # the "button" below does not do anything ??????
> >>     Button(root, text='Fetch', command=(fetch(vars))).pack(side=LEFT)
> >
> >Of course this doesn't work.  It calls 'fetch(vars)', and passes the
result
> >to 'Button'.  Use the lambda, that's what it's there for.  Or use one of
the
> >'curry' alternatives (see archives).
>
>
> My question is *why* the lambda is allowed to call the perfectly defined
function
> fetch, but a direct call of fetch is not.
>
> In other words --- I already knew that I had to use lambda, but I do not
know why!

Since I tripped over this a few times before I got it through my head,
here's an
attempt to explain.

In Python, functions are objects. If you say something like

>>>name = foo()

you're calling the function foo with a null parameter list, and the result
will be whatever foo() returns.

if you say

>>>name = foo

you're binding name to the function object "foo", not calling it. Later, you
can say something like

>>>name()

and it should return whatever foo() does!

When you use a lambda as a command arguement in a Tkinter call, you're
actually passing a function object to Tkinter. Later, Tkinter will invoke
that
function object when it needs to do a callback.

if you wanted to say "command = lambda: foo()", you could just as easily
say "command = foo". Notice the lack of parenthesis! What you can't do is
use this to pass parameters to foo, because that would cause it to be
executed,
rather than pass the function object.

Lambda gets around this problem with a "neat hack." When I say something
like:

command = lambda a=x, b=y: foo(a, b)

Then in effect I'm building an unnamed function definition, and assigning
default
values to the two parameters. Those default values will travel with the
definition,
so when Tkinter calls it later, they will be availible to the actual
execution.

The call of foo(a,b) in the definition above is part of the definition - it
won't be
executed until the function object is executed later.

John Roth
>
>
>
> Regards, Joe





More information about the Python-list mailing list