execfile() and locals()

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sun Aug 15 19:24:25 EDT 2010


On Sun, 15 Aug 2010 23:21:51 +0200, fons wrote:

> Hello all,
> 
> The documentation on execfile() and locals() makes it clear that code
> executed from execfile() can not modify local variables in the function
> from wich execfile() was called. Two questions about this:
> 
> 1. Is there some way to circumvent this limitation (apart from
> explicitly copying variables to/from a dictionary passed as locals to
> execfile()) ?

Chances are very good that if you're using exec or execfile inside a 
function, you probably don't need to.


> 2. (for experts only I guess) I'd like to understand *why* this is the
> case.

As an optimization, local variables don't live inside a dict namespace. 
The space for those locals is allocated at compile time, and locals() 
returns a copy of the variables in a dict.

However, the action of exec is a little more subtle, and mysterious, as 
seen by this example in Python 3.1:

>>> def f():
...     x = 1
...     print(locals())
...     exec("x=2; y=0")
...     print(locals())
...
>>>
>>> f()
{'x': 1}
{'y': 0, 'x': 1}

This shows that exec was able to create a new local variable, but not 
modify an existing one -- this is completely unintuitive to me. I would 
have guessed the opposite. And worse:

>>> f.__code__.co_varnames
('x',)
>>> f.__code__.co_nlocals
1

So where does the newly-created local `y` live, if not in a dict 
namespace and not in the usual variable slots?

Curiouser and curiouser... 



-- 
Steven



More information about the Python-list mailing list