Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python vars() global name error

Tags:

python

global

I'm having a bit of trouble understanding what's going wrong with the following function:

def ness():
 pie='yum'
 vars()[pie]=4
 print vars()[pie]
 print yum

So When I run that I get this result:

>>> ness()
4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in ness
NameError: global name 'yum' is not defined

If I don't write it as a function and just type it in on the command line one line at a time it works fine, like so:

>>> pie='yum'
>>> vars()[pie]=4
>>> print vars()[pie]
4
>>> print yum
4
>>> 

Edit: Suppose I wanted to make things a bit more complicated than this and instead of setting yum to a value and printing that value, I define some functions, and want to call one of them based on some input:

def ness(choo):
    dic={}
    dessert=()
    dnum=[10,100]
    desserts='pie'
    dic[dessert]=str(desserts[bisect(dnum,choo)])
    vars()[dic[dessert]]()
def p():
    print 'ummmm ummm'
def i():
    print 'hooo aaaaa'
def e():
    print 'woooo'

So when I call ness I get a key error:

>>> ness(3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in ness
KeyError: 'p'

Now I know I can do things like this with some elif statements, but I'm wondering if this would work too, and if using bisect like this would be more efficient (say if i need to check 1000 values of choo) than using elifs.

Thanks much for the assistance.

like image 997
Jamie Avatar asked Dec 02 '25 21:12

Jamie


2 Answers

vars() within a function gives you the local namespace, just like locals() -- see the docs. Outside of a function (e.g. at the prompt) locals() (and vars() of course) gives you the module's global namespace, just like globals(). As the docs say, trying to assign to a function's local variable through locals() (or equivalently, vars() inside a function) is not supported in Python. If you want to assign to a global variable, as you do when you're at the prompt (or otherwise outside of a function), use globals() instead of vars() (maybe not the cleanest approach -- global variables are understandably frowned upon -- but it does work).

like image 150
Alex Martelli Avatar answered Dec 04 '25 09:12

Alex Martelli


There is way to do it with exec

>>> def ness():
...  pie='yum'
...  exec pie+"=4"
...  print vars()[pie]
...  print yum
...
>>>
>>> ness()
4
4

But Instead of doing that, using a new dict is better and safe

>>> def ness():
...  dic={}
...  pie='yum'
...  dic[pie]=4
...  print dic[pie]
...  print dic['yum']
...
>>> ness()
4
4
>>>
like image 28
YOU Avatar answered Dec 04 '25 09:12

YOU



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!