eval's local arguement ignored?

Peter Abel PeterAbel at gmx.net
Fri Sep 26 11:45:42 EDT 2003


jseb at cs.mcgill.ca (Jean-Sébastien Bolduc) wrote in message news:<56e1eff0.0309230923.1215833f at posting.google.com>...
> Hello,
> 
> I would like to associate a local namespace with a lambda function. To
> be more specific, here is exactly what I would want:
> 
> def foo():
>   a = 1
>   f = lambda x : a*x
>   return f
> 
> then if "f1 = foo()", I get a function whose parameter "a" is not in
> the global scope. But my functions are not to be hard-coded. I naively
> expected the following to work:
> 
> def foo(funcstring):
>   a = 1
>   f = eval(funcstring)
>   return f
> 
> but "f2 = foo( 'lambda x : a*x' )" won't work: "f2()" will look for
> "a" in the globals.
> 
> Looking at the documentation (I did!), I was then certain replacing
> the evaluation with the following would work:
> 
>   f = eval(funcstring, globals(), locals())
> 
> Or, while we're at it, evaluating the whole thing outside of function
> "foo":
> 
> f = eval('lambda x : a*x', globals(), {'a' : 1})
> 
> Ooops! the new function still looks for "a" in the globals... Although
> I could not find any documentation about the fact, it seems the
> "local" argument to "eval" has no effect in the above cases!
> 
> So for now, I'm doing something like
> 
> f = eval('lambda x : a*x', {'a' : 1})
> 
> but then my function looses access to the globals.
> 
> I know that only the very first case above gives me a function whose
> "fun_closure" attribute is not "None". But still I cannot see where I
> go wrong.
> 
> Thank you,
> 
>    JSeb

**kwa** is the solution!

In your factory-function *foo* you have to declare *a*
keywordarguement which is initialized with a.

>>> def foo():
... 	a=1
... 	f=lambda x,a=a:a*x
... 	return f

>>> f1=foo()
>>> f1(3)
3

A global *a* doesn't affect your function.
>>> a=1000
>>> f1(3)
3

but you even can get influence to *a*:
>>> f1(3,a=100)
300
>>> 
or
>>> f1(3,100)
300
>>> 

And this works too, even if you generate a lambda-function
as adhoc-function in the global scope:
!! You have to define *a* as first !!
>>> a=100
>>> f2=lambda x,a=a:a*x
>>> f2(3)
300

To change the global *a* doesn't affect your lambda-function!
>>> a=0
>>> f2(3)
300

But you can give your function the additional information.
>>> f2(3,a=1)
3

or more traditional
>>> f2(3,1)
3

And the default kwa will stay resident.
>>> f2(3)
300
>>> 

Regards
Peter




More information about the Python-list mailing list