Repost: execfile() confusion

Steve Holden sholden at holdenweb.com
Sun Sep 30 11:22:34 EDT 2001


"Nathaniel Gray" <n8gray at caltech.edu.is.my.e-mail.address.com> wrote in
message news:9p6go5$c1l at gap.cco.caltech.edu...
> Steve Holden wrote:
> > "Nathaniel Gray" <n8gray at caltech.edu.is.my.e-mail.address.com> wrote
> >> [snip code]
> >> I though that execfile was supposed to act on the locals() of the scope
> >> from which it was called.  I also tried adding x=None to the top of
doit()
> >> but execfile still doesn't change its value to 'spam'.  Can somebody
> > please
> >> explain what's going on?
> >>
> > You have made a mistaken assumption, mistrusting the documentation when
in
> > fact everything is perfectly explicable as documented. Your assumption
is
> > that inside doit() the interpreter will check for x as a local before it
> > checks for x as a global.
> >
> > [snip explanation of compiler's analysis]
>
> The compiler don't enter into it.  <0.7 wink>  Well really it does,
somewhat,
> but it's not actually the problem.  I suspected that the compiler's
analysis
> was the problem and this is why I mentioned that I tried adding x=None to
the
> top of doit().  This was to force the compiler to recognize x as a local
> variable.  Unfortunately, in that case the assignment in test2.py has no
> effect.  Here's a slightly modified version of the files that will perhaps
make
> my confusion clear:
>
> #### test2.py ####
> print 'test2 locals:', locals().keys()
> x = 'spam'
> print 'Post-assignment test2 locals:', locals().keys()
>
> #### test.py ####
> def doit():
>     joe = 99
>     #x = 'not spam'  # THE MAGIC LINE
>     execfile( 'test2.py' ) # x = 'spam'
>     print 'x is now: %(x)s' % locals()   #No compiler tricks allowed!
> doit()
>
> Trial 1.  Here's the output with the "magic" line commented:
>         test2 locals: ['joe']
>         Post-assignment test2 locals: ['x', 'joe']
>         x is now: spam
>
> Trial 2.  And when you uncomment it:
>         test2 locals: ['joe', 'x']
>         Post-assignment test2 locals: ['joe', 'x']
>         x is now: not spam
>
> I just can't seem to find a consistent story here.  Clearly the assignment
is
> happening in the locals() of test2 as evidenced by the post-assignment
> printout.  Clearly the locals() of test2 should be the same as the
locals() of
> test, as evidenced by the fact that 'joe' shows up in test2's locals() and
the
> fact that 'x' shows up in doit()'s locals in trial 1.  Sorry, Sherlock,
but
> this is just nucking futs!  ;^)  Python seems to be waffling over whether
or
> not the assignment to x in test2.py does or does not happen in doit()'s
> locals() based on whether x was *already* in doit()'s locals()!
>
> By the way, this behavior is the same in Python 1.4, so if it's a bug it's
an
> old one.  Maybe there's a rational explanation for this, maybe it's a bug,
or
> maybe it's just a place on the Python map labeled "here there be
monsters", but
> in any case I'd sure like to understand it.  Maybe this is the excuse I've
been
> waiting for to dip into Python's guts...
>
> Thanks for your help,

Not a problem. If Tim Peters says it takes too long to explain, I'm
certainly not going to look for anything closer to the exact truth. Just put
that "here be dragons" label on your mental map and leave it at that -
whatever else you do, don't expect passing a locals() dict to help, as this
is explicitly *not* a good idea.

regards
 Steve
--
http://www.holdenweb.com/








More information about the Python-list mailing list