40

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.

1
  • 2
    Closing this question as duplicate with the reference is wrong. The other question is about USING global variables not ADDING global variables from a different namespace. Commented Aug 21, 2022 at 17:45

5 Answers 5

53

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.

Sign up to request clarification or add additional context in comments.

3 Comments

This is by far the best answer. No reason to do any weird magic like the other answers suggested. I'm just sad I didn't see this answer sooner.
IMO it would be a lot better to give the name_space argument to the function a default value of None and then, inside the function, use the calling function's globals as the default namespace when nothing else is given. i.e. if name_space is None: name_space = sys._getframe(1).f_globals. Doing this would allow this function to be more easily used by other scripts because the way it's currently coded, the default namespace is that of whatever script/module the insert_into_namespace() function itself is defined within—so would only be accessible to other functions in that same script.
Can you give a code example where the default value of parameter name_space above and the value of globals() in the current scope are different?
28

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()

2 Comments

It seems overwrite does not work, any idea how to make it work? var = 1; Global.var=2 ; print(var) (prints 1)
Because var is not in the builtin namespace, while Global.var is. Only the builtin namespace is include implicitly everywhere.
20

Yes, just use the global statement.

def func():
    global var
    var = "stuff"

8 Comments

What if you don't know the name of the variable until runtime?
@martineau: In the first place, that wasn't the original question. Anyway, in general if you're trying to assign to a variable whose name you don't know until runtime, you're probably doing something wrong. How will you later make use of that variable if you don't know what its name is? Usually if you're trying to create a variable with a certain name, you're better off making a dictionary and using the "name" as the key.
Yes, I know that wasn't the original question. As for a realistic use-case, consider a caller telling the function what name(s) to create via arguments and then using them afterwards in the same module with other code that assumes they're defined. A little like at a from xxx import yyy statement except yyy is a string.
@martineau: globals()['varname'] = 'varvalue'
@gsk: That well-known technique only inserts names into the namespace of the module in which the function resides which might not be the same one as the caller's.
|
8

A more terse version of Roland Puntaier's answer is:

import builtins

def insert_into_global_namespace():
    builtins.var = 'an object'

1 Comment

Out of dozens of "solutions" I tried, this is the ONLY one that actually worked, and is neat!
0

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']
########################################
  1. Python exec should be avoided for many reasons.

  2. N.B.: Note the lack of an "in" keyword on the "exec" line ("unqualified exec").

1 Comment

You can just do globals()[new_global_name] = new_global_value.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.