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
[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 "<stdin>", line 1, in <module>
File "<stdin>", line 4, in foo
UnboundLocalError: local variable 'y' referenced before assignment
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
>>>
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.
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).
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)