Reason for globals() in Python?

What is the reason of having globals() function in Python? It only returns dictionary of global variables, which are already global, so they can be used anywhere... I'm asking only out of curiosity, trying to learn python.

def F():
    global x
    x = 1

def G():
    print(globals()["x"]) #will return value of global 'x', which is 1

def H():
    print(x) #will also return value of global 'x', which, also, is 1

F()
G()
H()

I can't really see the point here? Only time I would need it, was if I had local and global variables, with same name for both of them

def F():
    global x
    x = 1

def G():
    x = 5
    print(x) #5
    print(globals()["x"]) #1

F()
G()

But you should never run into a problem of having two variables with same name, and needing to use them both within same scope.


Solution 1:

Python gives the programmer a large number of tools for introspecting the running environment. globals() is just one of those, and it can be very useful in a debugging session to see what objects the global scope actually contains.

The rationale behind it, I'm sure, is the same as that of using locals() to see the variables defined in a function, or using dir to see the contents of a module, or the attributes of an object.

Coming from a C++ background, I can understand that these things seem unnecessary. In a statically linked, statically typed environment, they absolutely would be. In that case, it is known at compile time exactly what variables are global, and what members an object will have, and even what names are exported by another compilation unit.

In a dynamic language, however, these things are not fixed; they can change depending on how code is imported, or even during run time. For that reason at least, having access to this sort of information in a debugger can be invaluable.

Solution 2:

It's also useful when you need to call a function using function's string name. For example:

def foo():
    pass

function_name_as_string = 'foo'

globals()[function_name_as_string]() # foo(). 

Solution 3:

You can pass the result of globals() and locals() to the eval, execfile and __import__ commands. Doing so creates a restricted environment for those commands to work in.

Thus, these functions exist to support other functions that benefit from being given an environment potentially different from the current context. You could, for example, call globals() then remove or add some variables before calling one of those functions.

Solution 4:

globals() is useful for eval() -- if you want to evaluate some code that refers to variables in scope, those variables will either be in globals or locals.


To expand a bit, the eval() builtin function will interpret a string of Python code given to it. The signature is: eval(codeString, globals, locals), and you would use it like so:

def foo():
    x = 2
    y = eval("x + 1", globals(), locals())
    print("y=" + y) # should be 3

This works, because the interpreter gets the value of x from the locals() dict of variables. You can of course supply your own dict of variables to eval.