Blog coding and discussion of coding about JavaScript, PHP, CGI, general web building etc.

Monday, July 25, 2016

Python vars() global name error

Python vars() global name error


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 "", line 1, in     File "", 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 "", line 1, in     File "", 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.

Answer by John La Rooy for Python vars() global name error


It's not safe to modify the dict returned by vars()

vars([object])?

Without an argument, act like locals().

With a module, class or class instance object as argument (or anything else that has a dict attribute), return that attribute.

Note

The returned dictionary should not be modified: the effects on the corresponding symbol table are undefined.

Your second example is a special case. vars() is equivalent to globals() in the global namespace, and the dict returned by globals() behaves as you would expect ( but is frowned upon )

>>> id(vars()),id(globals())  (3085426868L, 3085426868L)  

Answer by Alex Martelli for Python vars() global name error


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).

Answer by Mike Graham for Python vars() global name error


vars() is equivalent to locals(), which in the case of the function is the local variables in its scope and at in the interactive interpreter at the scope you have it, vars() is globals(). locals() is for reading only; the effects of trying to change it are undefined (and in practice, just doesn't work). globals() can be modified, but you still should never directly put anything in the dict it returns.

Answer by Johann Hibschman for Python vars() global name error


[Edit: I must be wrong here, since the 'exec' example works.]

As everyone points out, it's a bad idea to modify vars(). You can understand the error, though, by realizing that python in some sense doesn't "see" that "yum" is a local. "print yum" is still resolved as a global reference; this happens before any code is executed.

It's the same reason you get an UnboundLocalError from:

>>> y = 100  >>> def foo(x):  ...   if x == 1:  ...     y = 10  ...   print y  ...   >>> foo(1)  10  >>> foo(2)  Traceback (most recent call last):    File "", line 1, in     File "", line 4, in foo  UnboundLocalError: local variable 'y' referenced before assignment  

Answer by YOU for Python vars() global name error


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  >>>  


Fatal error: Call to a member function getElementsByTagName() on a non-object in D:\XAMPP INSTALLASTION\xampp\htdocs\endunpratama9i\www-stackoverflow-info-proses.php on line 72

0 comments:

Post a Comment

Popular Posts

Powered by Blogger.