exec(code) not allowing import on top level?

Peter Otten __peter__ at web.de
Tue Jul 29 07:48:39 EDT 2008


Peter Teuben wrote:

> 
> if I define a simple string code, with the following contents:
> 
> import math
> def foo(x):
>    return math.sqrt(x)

The 

import math 

statement puts 'math' in the local namespace, and foo looks it up in the
global namespace. This can only work when these namespaces are the same:

>>> code = """
... import math
... def foo(x):
...     return math.sqrt(x)
... print foo(2)
... """
>>> exec code in {}
1.41421356237
>>> exec code in {}, {}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 5, in <module>
  File "<string>", line 4, in foo
NameError: global name 'math' is not defined

You could argue that Python should always look into the local namespace and
then fall back to the global namespace but that would be fruitless extra
work in most cases. I think it can only hapen with exec/eval, and as you
have seen in the other responses even there it works on the module level
because -- tada!

>>> globals() is locals()
True
 
> and i run it using exec(code) in python, math is not known. But when I
> recode the string as:
> 
> def foo(x):
>    import math
>    return math.sqrt(x)

Here Python "guesses" that math is a local variable and that guess is
correct. If you wrote

import math
def foo(x):
    return math.sqrt(x)
    math = 42

Python would still guess that math is a local name and you would end up with
a runtime exception.

Peter



More information about the Python-list mailing list