lambda & scope
Alex Martelli
aleaxit at yahoo.com
Tue Nov 7 09:41:12 EST 2000
"John J. Lee" <phrxy at csv.warwick.ac.uk> wrote in message
news:Pine.SOL.4.30.0011062003110.29419-100000 at mimosa.csv.warwick.ac.uk...
[snip]
> say you have:
>
> def fred(variable, parameter):
> return parameter*variable**2
OK so far.
> and you want to do something in the spirit of:
>
> def wilma():
> (...)
> parameter = 3.4
> call_fred(lambda x: wilma(x, parameter), args, args, args)
The spirit is willing, but the flesh is weak. The recursive
call to wilma is a bother. I'll guess you mean something like:
def call_fred(funz, *args):
for arg in args:
something_wonderful(funz(arg))
and:
def wilma(parameter):
call_fred(lambda x: fred(x, parameter), 1.2, 3.4, 5.6, 7.8)
> Because you know that call_fred wants as its first argument a function
> that only takes one argument (above doesn't work due to Python's
> three-level scope).
...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.
> Probably 'don't do that' is a good answer, but I wondered if there was
> another one? Actually I think there is a way that would work in Mark
> Lutz's book, using a class, but is there a simpler way?
A class whose instances are callable is really a simple way to
do generic 'hand-built closures'. A lambda (with default
valued args for injection-into-scope) is simpler, though
a bit limited. A local function (with default valued args)
may give more flexibility (and it's no worse than a lambda
in terms of 'complication', you just to have to invent a name):
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)
Other ways tend to be more _complicated_, or at least _complex_
(and refined). For example, using the built-in 'new' module to
build a function-object on the fly from a code-object with a
chance to specify default-values...
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"...!-)
Alex
More information about the Python-list
mailing list