Reputation: 2814
I have an extern module where I want to set "exec" expressions as global (because I need to pass strings as variables names)
So, I have a function like
def fct_in_extern_module():
exec 'A = 42' in globals()
return None
and in my main script I have
import extern_module
extern_module.fct_in_extern_module()
Thus, why do I have
NameError: name 'A' is not defined
While if I do (in the main script)
def fct_in_main():
exec 'B = 42' in globals()
fct_in_main()
>>> B
42
Any idea how can I set the string 'A' as a variable name in a extern module ?
Thanks !
Upvotes: 2
Views: 154
Reputation: 310097
globals()
always returns the __dict__
of the module where it was called. This is really the only reasonable choice ... consider:
# qux.py
import foo
foo.bar()
# foo.py
import baz
def bar():
return baz.exec_stuff()
# baz.py
def exec_stuff():
exec 'A = 1' in globals()
Should the global be set in qux.py
or foo.py
or baz.py
? Looking at it this way, baz
is the most obvious choice and the one that python uses.
Now that brings us to the question of why are you using exec in the first place? Generally it's a much better idea to return the value you need to the caller. Then they can do what they wish with it:
def fn_in_extern_module():
return 42
and then:
import extern
A = extern.fn_in_extern_module()
Upvotes: 1
Reputation: 882421
globals()
means "the globals dict of this module". Thus, the way you have chosen to code extern_module.py
will not affect the globals dict of any other module.
One way to fix: define it as:
def fct_in_extern_module(where):
exec 'A = 42' in where
and call it as:
extern_module.fct_in_extern_module(globals())
Of course, as usual, exec
is not the best way to solve the problem. Better:
def fct_in_extern_module(where):
where['A'] = 42
faster and cleaner.
Upvotes: 4