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