Namespace Mystery (HELP!)

Warren L. DeLano warren at sunesis-pharma.com
Fri Jul 7 13:02:29 EDT 2000


Thanks to Paul Prescod for his concise answer.  Unfortunately that important
information was omitted from the otherwise excellent "Python: Essential
Reference".  However, the crux of my question really relates to the behavior
of the "exec" statement, and the fact that, with respect to local
variables...

   exec <code>

IS NOT EQUIVALENT TO

   exec <code-object> in globals()  # A
or
   exec <code-object> in globals(),locals()  # B

Okay, we now know why B doesn't work, but why is it that A doesn't work as
well?

I have small code fragments generated at runtime (from a command-line
interpreter) that I would like to execute within the local namespace of a
function, but which also have access to a separate global namespace (my own
namespace - not the global namespace).  I don't want to touch the global
namespace of the module (not thread safe). Thus I want to pass in:

# illustrative example

def fn(code,my_globals):
   a = 1
   b = 1
   exec "b=2" in my_globals
   return a+b

Assume that code contains references to variables in functions in the
my_globals dictionary, and that it alters the a and b variables.   The above
code won't work, because changes won't be preserved, even though I haven't
even provided locals to exec!

There is a workaround:

def fn(code):
    a = 1
    b = 1
    my_locals = locals()
    exec code in my_globals,my_locals
    return my_locals['a']+my_locals['b']

which is clearly awkward if you need to do anything more complex with a and
b...

Warren

Dag Sunde wrote:

> Warren,
>
> Aside from your question about the locals() and Pauls
> excellent answer, is there any particular reason
> you're not writing something like:
>
> >>> def fnx():
> ...  b = 1
> ...  global a
> ...  a = 2
> ...  b = 2
> ...  print a, b
>
> Dag.
>
> "Paul Prescod" <paul at prescod.net> wrote in message
> news:39656345.86AADA8A at prescod.net...
> > > Why is the output "2 1" and not "2 2"?
> > > What is it about the locals() function that makes it behave
> > > unexpectedly?
> >
> > locals ()
> > Return a dictionary representing the current local symbol table.
> > Warning: the contents of this dictionary should not be modified;
> changes
> > may not affect the values of local variables used by the interpreter.
> >
> > http://www.python.org/doc/lib/built-in-funcs.html
> >
> > Python doesn't typically look up local variables based on a string
> name
> > at runtime. That would be too inefficient. Rather it looks them up
> > positionally.
> >
> > --
> >  Paul Prescod - Not encumbered by corporate consensus
> > Pop stars come and pop stars go, but amid all this change there is one
> > eternal truth: Whenever Bob Dylan writes a song about a guy, the guy
> is
> > guilty as sin.
> > - http://www.nj.com/page1/ledger/e2efc7.html
> >

--
mailto:warren at sunesis-pharma.com
Warren L. DeLano, Ph.D.
Informatics Scientist
Sunesis Pharmaceuticals, Inc.
3696 Haven Ave., Suite C
Redwood City, CA 94063
(650)-556-8800 fax: (650)-556-8824





More information about the Python-list mailing list