[Chicago] dict to local vars?

Jonathan Helmus jjhelmus at gmail.com
Wed Jan 22 21:31:34 CET 2014


Brian,

     The eval function can take two optional arguments, globals and 
locals which allow you to specify name spaces [1].  If you set locals to 
the dictionary of values in question they will not pollute the global 
name space:

import numpy as np
def evaleq(eq,vals):
     return str(eval(eq, globals(), vals))
myeq = 'a*np.exp(b)'
myvals = {'a':1, 'b':0}
print evaleq(myeq,myvals)
print evaleq('2*Abc',{'Abc':21.})
print evaleq('2*Abc+a',{'Abc':21.})

When run this returns:

1.0
42.0
Traceback (most recent call last):
   File "problem.py", line 13, in <module>
     print evaleq('2*Abc+a',{'Abc':21.})
   File "problem.py", line 6, in evaleq
     return str(eval(eq, globals(), vals))
   File "<string>", line 1, in <module>
NameError: name 'a' is not defined

Note that the variable don't exist in the name space of the evaleq 
function either, so they cannot be reused.

[1] http://docs.python.org/2/library/functions.html#eval

Cheers,

     - Jonathan Helmus


On 01/22/2014 02:13 PM, Toby, Brian H. wrote:
> Can any Python gurus help me find a cleaner way to attack a problem? I 
> am of the opinion that /anything/ can be done in Python (though not 
> always cleanly or wisely), but so far how to define variables in the 
> local namespace from a dict has so far eluded me.
>
> Let me set the problem in context, in case there is a more pythonic 
> way to approach this task: I am working on a set of routines that will 
> evaluate an arbitrary expression. At least as I see myself framing the 
> problem right now, I will end up with a str with the equation and a 
> dict containing the values for each variable in the expression. I will 
> not know what variable names to expect in the expression, so I must 
> deal with them as strings at run-time.
>
> I want to evaluate the expression reasonably quickly (as I will later 
> need numerical derivatives). The code fragment below does almost 
> exactly what I want, except the values end up in the module's global 
> namespace, but I would prefer they were in the local namespace or that 
> of an object --- so that the 3rd call to evaleq would produce an 
> exception.
>
> import numpy as np
> def evaleq(eq,vals):
> for k,v in vals.iteritems(): globals()[k] = v
> return 'expression '+eq+' => '+str(eval(eq))
> myeq = 'a*np.exp(b)'
> myvals = {'a':1, 'b':0}
> print evaleq(myeq,myvals)
> print evaleq('2*Abc',{'Abc':21.})
> print evaleq('2*Abc+a',{'Abc':21.})
>
> Note that locals() is not supposed to be used in the way that I use 
> globals() above, at least as far as I understand, so that is not an 
> option.
>
> Any suggestions?
>
> Brian
>
> ********************************************************************
> Brian H. Toby, Ph.D.                            office: 630-252-5488
> Senior Physicist/Section Head for Scientific Software
> Advanced Photon Source
> 9700 S. Cass Ave, Bldg. 401/B4192
> Argonne National Laboratory
> Argonne, IL 60439-4856         e-mail: brian dot toby at anl dot gov
> ********************************************************************
> "We will restore science to its rightful place, and wield technology's 
> wonders... We will harness the sun and the winds and the soil to fuel 
> our cars and run our factories...  All this we can do. All this we 
> will do."
>
>
>
> _______________________________________________
> Chicago mailing list
> Chicago at python.org
> https://mail.python.org/mailman/listinfo/chicago

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/chicago/attachments/20140122/acfc8021/attachment.html>


More information about the Chicago mailing list