|  | exec(code) not allowing import on top level? |  | |
| | | Peter Teuben |  |
| Posted: Tue Jul 29, 2008 1:26 am Post subject: exec(code) not allowing import on top level? |  |
if I define a simple string code, with the following contents:
import math def foo(x): return math.sqrt(x)
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)
it works fine. That seemed like an inconsistency, since it works fine otherwise, as expected. It's easy to work around, but just odd to find this out.
thanks
peter |
| |
| | | Gary Herron |  |
| Posted: Tue Jul 29, 2008 2:17 am Post subject: Re: exec(code) not allowing import on top level? |  |
Peter Teuben wrote:
| Quote: | if I define a simple string code, with the following contents:
import math def foo(x): return math.sqrt(x)
|
What? You have not told us something important here. First, that code won't fail because it does not even execute the function foo -- it just defines it. Second, if I exend your string with one more line "foo(123)" to actually execute the code, it still works as expected.
So let's try this again... and this time please please also show us the full text of the error message.
Gary Herron
| Quote: | 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)
it works fine. That seemed like an inconsistency, since it works fine otherwise, as expected. It's easy to work around, but just odd to find this out.
thanks
peter -- LINK |
|
| |
| | | Gary Herron |  |
| Posted: Tue Jul 29, 2008 2:18 am Post subject: Re: exec(code) not allowing import on top level? |  |
Peter Teuben wrote:
| Quote: | if I define a simple string code, with the following contents:
import math def foo(x): return math.sqrt(x)
|
What? You have not told us something important here. First, that code won't fail because it does not even execute the function foo -- it just defines it. Second, if I extended your string with one more line "foo(123)" to actually execute the code, it still works as expected.
So let's try this again... and this time please please also show us the full text of the error message.
Gary Herron
| Quote: | 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)
it works fine. That seemed like an inconsistency, since it works fine otherwise, as expected. It's easy to work around, but just odd to find this out.
thanks
peter -- LINK |
|
| |
| | | Steven D'Aprano |  |
| Posted: Tue Jul 29, 2008 6:43 am Post subject: Re: exec(code) not allowing import on top level? |  |
On Tue, 29 Jul 2008 03:26:45 +0000, Peter Teuben wrote:
| Quote: | if I define a simple string code, with the following contents:
import math def foo(x): return math.sqrt(x)
and i run it using exec(code) in python, math is not known.
|
Works for me.
| Quote: | code = """import math .... def foo(x): |
.... return math.sqrt(x) .... """
| Quote: | exec code foo(25) 5.0 |
By the way, exec is a statement, not a function, so you don't need the brackets.
-- Steven |
| |
| | | Peter Otten |  |
| Posted: Tue Jul 29, 2008 9:48 am Post subject: Re: exec(code) not allowing import on top level? |  |
| |  | |
Peter Teuben wrote:
| Quote: | 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:
| Quote: | code = """ .... import math |
.... def foo(x): .... return math.sqrt(x) .... print foo(2) .... """
| Quote: | 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!
| Quote: | globals() is locals() True |
| Quote: | 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 |
| |
|
|