problem with namespaces using eval and exec

Peter Otten __peter__ at web.de
Tue May 16 06:05:03 EDT 2006


Jens wrote:

> has anyone an idea why the following code does not work.

> s = """
> def a(n):
>   return n*n

> def b(t):
>   return a(t)
> """

> ns = {}
> exec(s, {}, ns)

Here you are providing a local namespace into which all toplevel names (a
and b) are inserted.

> eval("b(2)", ns, {})

Here you provide a global (the former local) namespace containing an 'a'.
Function b(), however is carrying its global namespace with it and will
look for 'a' in that namespace and not the one you provide. This is similar
to

module x.py
def b(t): return a(t)

module y.py
import x
def a(t): return n * n
x.b(2) # error, will not find the function a() you just defined

Instead you could explicitly update b's global namespace:

global_ns = {}
local_ns = {}
exec s in global_ns, local_ns
global_ns["a"] = local_ns["a"]
print eval("b(2)", local_ns)

or (better, I think) model the situation of an ordinary module where
globals() and locals() are identical:

global_ns = {}
exec s in global_ns
print eval("b(2)", global_ns)

Peter





More information about the Python-list mailing list