eval's local arguement ignored?

Peter Abel PeterAbel at gmx.net
Tue Sep 30 18:05:32 EDT 2003


jseb at cs.mcgill.ca (Jean-S?bastien Bolduc) wrote in message news:<56e1eff0.0309300536.51fdf2b0 at posting.google.com>...
> > **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
> 
> Not exactly what I'm looking for, I'm afraid. A more complete picture
> is this: I'm writing a class such as this:
> 
> class Foo:
>   def __init__(self, fnc, **params):
>     ...
>   def evaluate(self, val)
>     ...
> 
> That has to be instantiated as, e.g.:
> 
> x = Foo( 'lambda x : a*x', dict( a = 2. ) )
> 
> so that "x.evaluate( 5. )" will return, in this case, "2.*5.".
> 
> The approach you describe will certainly work, but the thing is that
> this class will have to be used by people who don't necessarily know
> Python (yet). So I would really like the lambda function's parameter
> list to always be the same, whatever you put on its RHS.
> 
> Once again, I don't understand why the "eval", as described above with
> "globals" and "locals" arguments specified, will not work. Is there a
> way to modify a function's closure?
> 
> Thanks,
> JSeb

Sorry, I missunderstood you.
Since your last post I learned the further more two
parameters of the eval-function. I'm even not sure
if I checked the problem entirely, but let me try to
explain what I think I may have understood.

In the following function the eval-statement doesn't
really need the locals() to evaluate the lambda-function.
It really needs to tell the lambda where is its parent's
namespace - what is by default the modules-namespace which
one calls *globals()* - where to search for variables when
not found in the locals().

>>> def new_fn(fn_string):
... 	a=99999
... 	print locals()
... 	local_fun=eval(fn_string,globals(),locals())
... 	return local_fun
... 

I think the locals() are always the variables of a function's
body - in the above case of the function *new_fn*.

>>> f=new_fn('lambda x:(x*a,locals())')
will show that:
{'a': 99999, 'fn_string': 'lambda x:(x*a,locals())'}

So the following let us know what locals() means 
for the lambda-function:
>>> a=0
>>> f(10)
(0, {'x': 10})
>>> 
But *a* is found in the global-scope.
I'm not sure if this really helps you and the only
workaround for me is something I posted to you the last time.

What makes me more confused is the following example, where
the lambda-function is declared explicitly.

>>> def new_fn():
... 	a=99999
... 	print locals()
... 	local_fun=lambda x:(x*a,locals())
... 	return local_fun
... 
>>> f=new_fn()
{'a': 99999}
>>> a=0
>>> f(10)
(999990, {'a': 99999, 'x': 10})
>>> 

But I think that's what you did already.

PS: I here someone whispering something of *nested scopes*.

Regards
Peter




More information about the Python-list mailing list