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

Chris Rebert clp2 at rebertia.com
Tue Apr 21 14:37:23 EDT 2009


On Tue, Apr 21, 2009 at 11:25 AM, Doron Tal <doron.tal.list at gmail.com> wrote:
> On Tue, Apr 21, 2009 at 9:13 PM, Chris Rebert <clp2 at rebertia.com> wrote:
>>
>> On Tue, Apr 21, 2009 at 9:08 AM, Doron Tal <doron.tal.list at gmail.com>
>> wrote:
>> > Hi,
>> >
>> > Recently I tried to execute a python file using execfile (exec performed
>> > just the same for that reason).
>> > I encountered the behavior below:
>> >
>> > """
>> > $ cat execme.py
>> > a = 2
>> > $ python
>> > Python 2.4.3 (#1, May 24 2008, 13:57:05)
>> > [GCC 4.1.2 20070626 (Red Hat 4.1.2-14)] on linux2
>> > Type "help", "copyright", "credits" or "license" for more information.
>> >>>> def execfile_func():
>> > ...     execfile('execme.py')
>> > ...     print 'locals() = %s' % str(locals())
>> > ...     print a
>> > ...
>> >>>> execfile_func()
>> > locals() = {'a': 2}
>> > Traceback (most recent call last):
>> >   File "<stdin>", line 1, in ?
>> >   File "<stdin>", line 4, in execfile_func
>> > NameError: global name 'a' is not defined
>> >>>>
>> > """
>> >
>> > After execfile, the a variable can be found in locals(), however any
>> > direct
>> > reference (e.g., print a) fails.
>> > Is it expected?
>>
>> Yes. See http://docs.python.org/library/functions.html#locals (emphasis
>> mine):
>>
>> locals()
>>    [...]
>>    Warning: The contents of this dictionary should not be modified;
>> ***changes may not affect the values of local variables used by the
>> interpreter***.
>>    [...]
>>
>> Cheers,
>> Chris
>> --
>> I have a blog:
>> http://blog.rebertia.com
>
> (Chris - sorry for the multiple replies, I forgot to reply all)
>
> I actually did not attempt to modify this dictionary (the one which locals()
> returns) explicitly.

Well, it can be reasonably inferred that execfile() does.

> The simplest assignment command, such as 'a = 2' modifies this dictionary
> implicitly, and it's working perfectly well.

While the exec'd file may run fine using the locals() dict (or any
dict for that matter), that doesn't say anything about whether the
changes to locals() will actually be reflected in the local namespace
it came from, which indeed, as documented, it's not. execfile() may
use the locals() dict for all its variable lookups, but the plain
toplevel interpreter is allowed not to.

> I expected exec to work the same, but apparently I was wrong. Is there is a
> way to exec a file "more" correctly? thus avoid the need to resort to
> awkward solutions such as using the locals() dictionary?

I don't know personally. Perhaps a kind soul will chime in.

Cheers,
Chris

-- 
I have a blog:
http://blog.rebertia.com



More information about the Python-list mailing list