lambda & scope

Alex Martelli aleaxit at yahoo.com
Wed Nov 8 17:25:23 EST 2000


"John J. Lee" <phrxy at csv.warwick.ac.uk> wrote in message
news:Pine.SOL.4.30.0011081625020.22559-100000 at mimosa.csv.warwick.ac.uk...
    [snip]
> > ...and can be made to work easily and classically with "hand-built
> > closure":
> >
> > def wilma(parameter):
> >     call_fred(lambda x, parm=parameter: fred(x, parm), 1.2, 3.4, 5.6,
> 7.8)
> >
> > the 'default-valued argument' parm injects its default-value in
> > the lambda's scope, with its name.
>
> But then you end up with another function with two variables, don't you?

The lambda that I'm passing as the first element of call_fred
does have two _variables_ (x and parm), but what matters?

It only has _one_ *mandatory* parameter, since the second
one has a default value.  It can be (and is) called with one
parameter, therefore, and all is fine.

> You could always just change the function (fred()) that you want to call,
> but it's annoying that while you can get a one-argument function from an
> n-argument function when you're in the global scope, you can't do the same
> when you're inside a function (apparently).

Yes you can (do 'currying', and other kinds of closures) -- using
arguments-with-default-values, etc, etc.


> > def wilma(parameter):
> >     def localfun(x, parm=parameter):
> >         # you can insert statements here...
> >         return fred(x, parm)
> >     call_fred(localfun, 1.2, 3.4, 5.6, 7.8)
>
> But that's a function of two variables still.  I can't remember the exact

localfun has 2 (local) variables, which are both parameters,
but only one of them is actually passed (the second one,
having a default value, need not be passed in the call; so,
localfun is callable with one argument -- just like the
previous lambda was).

> circumstances now (I rewrote it a better way), but roughly the reason I
> wanted to do this was because I have a function that expects a function as
> a argument, and that (latter) function is expected by the (former)
> function to take only one argument.  Er, hope that's clear...

A function with two args, of which the second has a default
value, *IS* callable with 'only one argument'; that's the
whole point!


> In the local function you have above, python would complain, when it got
> around to calling localfun from within call_fred, that localfun has two
> formal parameters whereas it was only given one argument in the function
> call.

Nope!  Have you _tried_...?


> > import new
> >
> > def wilma3(parameter):
> >     afunc = new.function(fred.func_code,globals(),'fred',(parameter,))
> >     call_fred(afunc, 1.2, 3.4, 5.6, 7.8)
> >
> > ...but I wouldn't exactly call this "simpler"...!-)
>
> Aha, I think (haven't read the documentation for 'new' yet) that's what I
> was looking for - thanks.

This is not doing anything substantially different, actually; the
last parameter to new.function just indicates the tuple of
default-values for fred.func_code's arguments...!-)


Alex






More information about the Python-list mailing list