Question about name scope

Ian Kelly ian.g.kelly at gmail.com
Thu Feb 2 00:00:02 CET 2012


On Wed, Feb 1, 2012 at 3:53 PM, Ethan Furman <ethan at stoneleaf.us> wrote:
> --> def f(x, y):
>
> ...     locals()[x] = y
> ...     print(vars())
> ...     exec('print (' + x + ')')
> ...     print(x)
> ...
> --> f('a', 42)
>
> {'y': 42, 'x': 'a', 'a': 42}
> 42
> a
>
> Indeed -- the point to keep in mind is that locals() can become out of sync
> with the functions actual variables.  Definitely falls in the camp of "if
> you don't know *exactly* what you are doing, do not play this way!"

Sure, but that's not actually out of sync.  The argument of your exec
evaluates to 'print (a)'.  You get two different results because
you're actually printing two different variables.  You can get the
dict temporarily out of sync:

>>> def f(x, y):
...     frob = None
...     loc = locals()
...     loc[x] = y
...     print(loc)
...     print(locals())
...     print(loc)
...
>>> f('frob', 42)
{'y': 42, 'x': 'frob', 'frob': 42, 'loc': {...}}
{'y': 42, 'x': 'frob', 'frob': None, 'loc': {...}}
{'y': 42, 'x': 'frob', 'frob': None, 'loc': {...}}

In this case, 'frob' is updated to 42 in the dict, but the optimized
local is not updated.  Calling locals() again refreshes the dict.



More information about the Python-list mailing list