embedding python in python

Jeff Shannon jeff at ccvcorp.com
Thu Sep 30 21:13:00 EDT 2004


Maurice LING wrote:

> Please pardon me for my dumbness but what exactly goes on in
>
> exec "b = 1 + 2" in myglobals, mylocals


What's happening is that I've provided two dictionaries for exec to use 
as a global namespace and a local namespace, respectively.  In this 
particular example, both namespaces are empty, but we're not looking up 
any names in those namespaces, so that doesn't matter.  We *are* binding 
a name ('b') in the local namespace.  That local namespace is the dict 
I've named mylocals, so when exec is finished I can reference 
mylocals['b'] and find the value that 'b' was bound to inside the exec 
statement.

The next example is a bit more complex.  I'm passing the same 
dictionaries, but now the local namespace contains that reference to 
'b'.  The exec statement looks up that name, finds that it's bound to 
the value 3, multiplies that value by 2, and binds the result to 'c', 
again all in the local namespace (which is still the mylocals dict).  
Now I've got *two* names bound in mylocals -- 'b' and 'c'.

Note that my initial dictionaries don't need to be empty.  Just as was 
demonstrated in the second example, if there are entries in those 
dictionaries then the exec'd code can refer to them as if they were 
normal (global or local) variable names.  This also means that exec'd 
code can't refer to any *other* global or local variables --

 >>> myglobals = {}
 >>> mylocals = {}
 >>> foo = 5
 >>> exec "bar = foo * 5"
 >>> bar
25
 >>> exec "bar = foo * 5" in myglobals, mylocals
Traceback (most recent call last):
  File "<interactive input>", line 1, in ?
  File "<string>", line 1, in ?
NameError: name 'foo' is not defined
 >>> myglobals['foo'] = 10
 >>> exec "bar = foo * 5" in myglobals, mylocals
 >>> mylocals
{'bar': 50}
 >>>

When using a bare exec, the current local and global namespaces are 
used, so exec finds 'foo' and binds 'bar'.  But when I give exec two 
empty dicts, the name 'foo' is undefined within the exec statement, even 
though it exists in the interpreter's namespace.  After creating 'foo' 
within myglobals, though, exec can find it, and then binds 'bar' within 
mylocals.

In short, you can carefully construct a global and local namespace for 
your exec'd code, which contains only those variables that you *want* 
that code to see.  If that exec'd code binds any new variable names, 
then those names will remain in those namespaces when exec is done, so 
you can retrieve them later.

Jeff Shannon
Technician/Programmer
Credit International




More information about the Python-list mailing list