Exec Statement Question

  • Thread starter =?ISO-8859-1?Q?Gregory_Pi=F1ero?=
  • Start date
?

=?ISO-8859-1?Q?Gregory_Pi=F1ero?=

I'm curious why this code isn't working how I expect it to:

import sys
d=3

def func1(a,b,c):
print a,b,c,d
print sys.path

exec "func1(1,2,3)" in {'func1':func1}

----
returns:
1 2 3 3
[ sys.path stuff ....]

Since I'm telling exec to operate only within the context of the
dictionary I give it, why does it still see sys.path and d? I figured
it would throw a NameError.

Is there a way to call exec such that it won't have access to any more
objects than I explicitly give it?

Thanks,

Greg
 
7

7stud

I'm curious why this code isn't working how I expect it to:

import sys
d=3

def func1(a,b,c):
print a,b,c,d
print sys.path

exec "func1(1,2,3)" in {'func1':func1}

----
returns:
1 2 3 3
[ sys.path stuff ....]

Since I'm telling exec to operate only within the context of the
dictionary I give it, why does it still see sys.path and d? I figured
it would throw a NameError.

Is there a way to call exec such that it won't have access to any more
objects than I explicitly give it?

Thanks,

Greg

I think the way it works is that when the def is parsed, a function
object is created and assigned to the name func1. When the function
object is created, d is "bound" to the global value 3, while a,b,c lie
in wait for arguments to land in their gullets like venus fly traps.
Your dictionary has a key whose value is a reference to the function
object, which already has the value 3 bound to d.
 
A

Alex Martelli

Gregory Piñero said:
I'm curious why this code isn't working how I expect it to:

import sys
d=3

def func1(a,b,c):
print a,b,c,d
print sys.path

exec "func1(1,2,3)" in {'func1':func1}

----
returns:
1 2 3 3
[ sys.path stuff ....]

Since I'm telling exec to operate only within the context of the
dictionary I give it, why does it still see sys.path and d? I figured
it would throw a NameError.

Is there a way to call exec such that it won't have access to any more
objects than I explicitly give it?

func1 accesses its globals through func1.func_globals (which you can't
reassign -- it's a read-only attribute).

You may make a new function object w/ a different globals dict...:

and that will fail (even when called directly, but similarly if exec'd)
as it's missing key 'd' in its globals:
1 2 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in func1
NameError: global name 'd' is not defined


The globals dict you pass to exec is the globals at the time of CALL,
not the globals seen from INSIDE func1; that's always going to be the
func_globals attribute of the function object, so you need to control
that (by suitably building a new function object as you require).


Alex
 
G

Gabriel Genellina

7stud said:
I think the way it works is that when the def is parsed, a function
object is created and assigned to the name func1. When the function
object is created, d is "bound" to the global value 3, while a,b,c lie
in wait for arguments to land in their gullets like venus fly traps.
Your dictionary has a key whose value is a reference to the function
object, which already has the value 3 bound to d.

Not exactly. As Georg Brandl said, the function has a reference to the
*globals* currently in use when it was defined, not directly to the
name "d".

To the OP: If you want a function with almost "empty" globals, compile
it the same way you used to execute it:
.... print a
.... print b
....
.... func1(3)
.... print func1.func_globals.keys()
.... """3
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<string>", line 5, in ?
3
123
['__builtins__', 'func1', 'b']
I said *almost* empty because Python may insert other keys into the
globals, like __builtins__ above (see http://docs.python.org/ref/exec.html)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
474,201
Messages
2,571,048
Members
47,650
Latest member
IanTylor5

Latest Threads

Top