[Chicago] dict to local vars?

Japhy Bartlett japhy at pearachute.com
Thu Jan 23 06:31:25 CET 2014


Another way to approach an awkward situation like this maybe is to
reconsider why you need to evaluate arbitrary functions as strings!

What if you converted the strings into proper functions first, maybe a
class that implements __call__()?  Then you can __call__(
**yourlocaldict.keys() )



On Wed, Jan 22, 2014 at 8:40 PM, Yarko Tymciurak <yarkot1 at gmail.com> wrote:

> There's this tidbit, too (just for completeness):
>
> http://stackoverflow.com/questions/7973709/adding-exec-pass-to-a-function-allows-modifications-of-locals-to-be-reflec
>
>
>
> On Wed, Jan 22, 2014 at 3:46 PM, Adam Forsyth <adam at adamforsyth.net>wrote:
>
>> You can't depend on updating locals inside a function or other inner
>> scope. The behavior is undefined. It works at module level because there is
>> no separate locals -- you're updating globals.
>>
>>
>> On Wed, Jan 22, 2014 at 3:35 PM, Michael Tobis <mtobis at gmail.com> wrote:
>>
>>> oops I mean
>>>
>>> locals().update(mydict)
>>>
>>>
>>> On Wed, Jan 22, 2014 at 3:35 PM, Michael Tobis <mtobis at gmail.com> wrote:
>>>
>>>> locals.update(mydict)
>>>>
>>>> example:
>>>>
>>>> >>> mydict = {"foo" : "bazz"}
>>>> >>> mydict["foo"]
>>>> 'bazz'
>>>> >>> foo
>>>>
>>>> Traceback (most recent call last):
>>>>   File "<stdin>", line 1, in <module>
>>>> NameError: name 'foo' is not defined
>>>> >>> locals().update(mydict)
>>>> >>> foo
>>>> 'bazz'
>>>>
>>>>
>>>>
>>>> On Wed, Jan 22, 2014 at 2:22 PM, Adam Forsyth <adam at adamforsyth.net>wrote:
>>>>
>>>>> 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
>>>>>>
>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Chicago mailing list
>>>>> Chicago at python.org
>>>>> https://mail.python.org/mailman/listinfo/chicago
>>>>>
>>>>>
>>>>
>>>
>>> _______________________________________________
>>> Chicago mailing list
>>> Chicago at python.org
>>> https://mail.python.org/mailman/listinfo/chicago
>>>
>>>
>>
>> _______________________________________________
>> Chicago mailing list
>> Chicago at python.org
>> https://mail.python.org/mailman/listinfo/chicago
>>
>>
>
> _______________________________________________
> 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/94ab0430/attachment-0001.html>


More information about the Chicago mailing list