Question about name scope

Ethan Furman ethan at stoneleaf.us
Thu Feb 2 00:41:59 CET 2012


Ian Kelly wrote:
> 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.

Ah -- thanks, I missed that.


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

I'm not sure what you mean by temporary:

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

Seems to be stuck that way.

Here is a better example I was thinking of:

--> def f(x, y):
...     locals()[x] = y
...     locals()['x'] = 17
...     print(locals())
...     print(x)
...     print(y)
...
--> f('a', 42)
{'y': 42, 'x': 'a', 'a': 42}
a
42

So locals() was updated with 'a', but not with the assignment to 'x'. 
And of course, if we tried to 'print(a)' we'd get a NameError.

~Ethan~



More information about the Python-list mailing list