[Chicago] dict to local vars?

Adam Forsyth adam at adamforsyth.net
Wed Jan 22 21:22:44 CET 2014

I'll assume you know this is bad and that there are existing libraries to
solve this problem.

There isn't a good way to modify locals. Instead, I think you want to use
the optional arguments to eval that allow you to provide dictionaries to
use in place of the real locals and globals.

import math
def evaleq(eq,vals):
    return 'expression '+eq+' => '+str(eval(eq,globals(),vals))
myeq = 'a*math.log(b)'
myvals = {'a':3, 'b':2}
print evaleq(myeq,myvals)
print evaleq('2*Abc',{'Abc':21.})
print evaleq('2*Abc+a',{'Abc':21.})

expression a*math.log(b) => 2.07944154168
expression 2*Abc => 42.0
Traceback (most recent call last):
  File "eval.py", line 8, in <module>
    print evaleq('2*Abc+a',{'Abc':21.})
  File "eval.py", line 3, in evaleq
    return 'expression '+eq+' => '+str(eval(eq,globals(),vals))
  File "<string>", line 1, in <module>
NameError: name 'a' is not defined

On Wed, Jan 22, 2014 at 2:13 PM, Toby, Brian H. <toby at anl.gov> 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/33d576e4/attachment.html>

More information about the Chicago mailing list