Reputation: 42463
I need to execute some dynamically generated code in Python and ensure that this code will have access to some custom global values, for example 'bar'. Based on python documentation i assembled the following test code:
def foo() : print( globals() )
exec "foo()" in dict( globals(), bar = 1 )
According to documentation, calling foo()
from exec
with bar
added to scope will list bar
among globals()
inside foo()
body. But the actual output is:
{'__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:\\Users\\Eye\
\Documents\\first.py', '__package__': None, '__name__': '__main__', 'foo': <func
tion foo at 0x01DD40F0>, '__doc__': None}
No bar
here :(. How to make bar
accessible from within code executed in exec
?
Upvotes: 2
Views: 2393
Reputation: 42463
I have found a suitable solution:
def foo() : print( foo.bar )
exec "foo.bar = bar\n" + "foo()" in dict( globals(), bar = 1 )
Upvotes: 0
Reputation: 1423
According to the documentation, when globals() is called from within a function it returns the dictionary for the module in which the function was defined.
If you create the new global AND pass it as an argument, you should be able to call functions dynamically. For example,
def foo(bar):
print bar
exec "foo(bar)" in dict(globals(), bar = "hello")
Upvotes: 2
Reputation: 34272
(I'm skipping here a usual rant about how generally bad and insecure is exec
)
If you try this:
exec "print globals().get('bar')" in dict( globals(), bar = 1 )
you will see that it works as expected.
When you define a function, it's bound with it's module's namespace, that's what it sees as globals. You can reach those bindings via foo.func_globals
. That's how a function can access module internals via globals, but cannot see the caller's environment (where bar
is defined).
Upvotes: 3
Reputation: 16037
sorry, what is the problem with this?
def foo() : print( globals() )
bar = 1
exec "foo()"
{'bar': 1, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', 'foo': <function foo at 0x7fd1b3954ed8>, '__doc__': None}
Upvotes: 0