Insert variable into global namespace from within a function?
Question:
Is it possible to add an object to the global namespace, for example, by using globals()
or dir()
?
def insert_into_global_namespace(var_name, value):
globals()[var_name] = value
insert_into_global_namespace('my_obj', 'an object')
print(f'my_obj = {my_obj}')
But this only works in the current module.
Answers:
Yes, just use the global
statement.
def func():
global var
var = "stuff"
But be aware that assigning function variables declared global only injects into the module namespace. You cannot use these variables globally after an import:
from that_module import call_that_function
call_that_function()
print(use_var_declared_global)
and you get
NameError: global name 'use_var_declared_global' is not defined
You would have to do import again to import also those new “module globals”.
The builtins module is “real global” though:
class global_injector:
'''Inject into the *real global namespace*, i.e. "builtins" namespace or "__builtin__" for python2.
Assigning to variables declared global in a function, injects them only into the module's global namespace.
>>> Global= sys.modules['__builtin__'].__dict__
>>> #would need
>>> Global['aname'] = 'avalue'
>>> #With
>>> Global = global_injector()
>>> #one can do
>>> Global.bname = 'bvalue'
>>> #reading from it is simply
>>> bname
bvalue
'''
def __init__(self):
try:
self.__dict__['builtin'] = sys.modules['__builtin__'].__dict__
except KeyError:
self.__dict__['builtin'] = sys.modules['builtins'].__dict__
def __setattr__(self,name,value):
self.builtin[name] = value
Global = global_injector()
I don’t think anyone has explained how to create and set a global variable whose name is itself the value of a variable.
Here’s an answer I don’t like, but at least it works[1], usually[2].
I wish someone would show me a better way to do it. I have found several use cases and I’m actually using this ugly answer:
########################################
def insert_into_global_namespace(
new_global_name,
new_global_value = None,
):
executable_string = """
global %s
%s = %r
""" % (
new_global_name,
new_global_name, new_global_value,
)
exec executable_string ## suboptimal!
if __name__ == '__main__':
## create global variable foo with value 'bar':
insert_into_global_namespace(
'foo',
'bar',
)
print globals()[ 'foo']
########################################
-
Python exec should be avoided for many reasons.
-
N.B.: Note the lack of an “in” keyword on the “exec” line (“unqualified exec”).
It is as simple as
globals()['var'] = "an object"
and/or
def insert_into_namespace(name, value, name_space=globals()):
name_space[name] = value
insert_into_namespace("var", "an object")
Remark that globals
is a built-in keyword, that is, 'globals' in __builtins__.__dict__
evaluates to True
.
A more terse version of Roland Puntaier’s answer is:
import builtins
def insert_into_global_namespace():
builtins.var = 'an object'
Is it possible to add an object to the global namespace, for example, by using globals()
or dir()
?
def insert_into_global_namespace(var_name, value):
globals()[var_name] = value
insert_into_global_namespace('my_obj', 'an object')
print(f'my_obj = {my_obj}')
But this only works in the current module.
Yes, just use the global
statement.
def func():
global var
var = "stuff"
But be aware that assigning function variables declared global only injects into the module namespace. You cannot use these variables globally after an import:
from that_module import call_that_function
call_that_function()
print(use_var_declared_global)
and you get
NameError: global name 'use_var_declared_global' is not defined
You would have to do import again to import also those new “module globals”.
The builtins module is “real global” though:
class global_injector:
'''Inject into the *real global namespace*, i.e. "builtins" namespace or "__builtin__" for python2.
Assigning to variables declared global in a function, injects them only into the module's global namespace.
>>> Global= sys.modules['__builtin__'].__dict__
>>> #would need
>>> Global['aname'] = 'avalue'
>>> #With
>>> Global = global_injector()
>>> #one can do
>>> Global.bname = 'bvalue'
>>> #reading from it is simply
>>> bname
bvalue
'''
def __init__(self):
try:
self.__dict__['builtin'] = sys.modules['__builtin__'].__dict__
except KeyError:
self.__dict__['builtin'] = sys.modules['builtins'].__dict__
def __setattr__(self,name,value):
self.builtin[name] = value
Global = global_injector()
I don’t think anyone has explained how to create and set a global variable whose name is itself the value of a variable.
Here’s an answer I don’t like, but at least it works[1], usually[2].
I wish someone would show me a better way to do it. I have found several use cases and I’m actually using this ugly answer:
########################################
def insert_into_global_namespace(
new_global_name,
new_global_value = None,
):
executable_string = """
global %s
%s = %r
""" % (
new_global_name,
new_global_name, new_global_value,
)
exec executable_string ## suboptimal!
if __name__ == '__main__':
## create global variable foo with value 'bar':
insert_into_global_namespace(
'foo',
'bar',
)
print globals()[ 'foo']
########################################
-
Python exec should be avoided for many reasons.
-
N.B.: Note the lack of an “in” keyword on the “exec” line (“unqualified exec”).
It is as simple as
globals()['var'] = "an object"
and/or
def insert_into_namespace(name, value, name_space=globals()):
name_space[name] = value
insert_into_namespace("var", "an object")
Remark that globals
is a built-in keyword, that is, 'globals' in __builtins__.__dict__
evaluates to True
.
A more terse version of Roland Puntaier’s answer is:
import builtins
def insert_into_global_namespace():
builtins.var = 'an object'