execfile (exec?) create non consistent locals() state

Peter Otten __peter__ at web.de
Wed Apr 22 08:11:18 EDT 2009


[original post is not on my news server]

[Doron Tal]

>>> > Recently I tried to execute a python file using execfile (exec
>>> > performed just the same for that reason).

Not over here:

Python 2.4.4 (#2, Aug  1 2008, 00:04:43)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def f():
...     execfile("execme.py")
...     print "locals:", locals()
...     print a
...
>>> f()
locals: {'a': 2}
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 4, in f
NameError: global name 'a' is not defined
>>> def g():
...     exec open("execme.py").read()
...     print "locals:", locals()
...     print a
...
>>> g()
locals: {'a': 2}
2

The reason is that while execfile() is just an ordinary function the exec
statement affects the function's bytecode (LOAD_NAME instead of LOAD_GLOBAL
or LOAD_FAST). This leads to the following Voodoo:

>>> def h():
...     exec ""
...     execfile("execme.py")
...     print "locals:", locals()
...     print a
...
>>> h()
locals: {'a': 2}
2

While this is certainly not the most regular behaviour it allows to avoid
going through a dictionary for every assignment in functions that don't
have an exec statement, thus giving you faster code in the vast majority of
cases at the cost of a few quirks like the one you encountered.

Peter




More information about the Python-list mailing list