osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

exec and globals and locals ...


Eko palypse wrote:

> No, I have to correct myself
> 
> x = 5
> def f1():
>     exec("x = x + 1; print('f1 in:', x)")
>     return x
> print('f1 out', f1())
> 
> results in the same, for me confusing, results.
> 
> f1 in: 6
> f1 out 5

Inside a function exec assignments go to a *copy* of the local namespace.
Also LOAD_NAME is used to look up names. Therefore you can read and then 
shade a global name with its local namesake.

Inside a function the namespace is determined statically. As f1() has no 
assignment to x (code inside exec(...) is not considered) x is looked up in 
directly the global namespace using LOAD_GLOBAL.

If you want to access the local namespace used by exec() you have to provide 
one explicitly:

>>> x = 5
>>> def f():
...     ns = {}
...     exec("x += 1", globals(), ns)
...     return ns["x"]
... 
>>> f()
6
>>> x
5

By the way, in Python 2 where exec was a statement the local namespace is 
shared:

>>> x = 5
>>> def f():
...     exec "x += 1"
...     return x
... 
>>> f()
6
>>> x
5