How can I access global variable inside class in Python How can I access global variable inside class in Python python python

How can I access global variable inside class in Python


By declaring it global inside the function that accesses it:

g_c = 0class TestClass():    def run(self):        global g_c        for i in range(10):            g_c = 1            print(g_c)

The Python documentation says this, about the global statement:

The global statement is a declaration which holds for the entire current code block.


You need to move the global declaration inside your function:

class TestClass():    def run(self):        global g_c        for i in range(10):            g_c = 1            print(g_c)

The statement tells the Python compiler that any assignments (and other binding actions) to that name are to alter the value in the global namespace; the default is to put any name that is being assigned to anywhere in a function, in the local namespace. The statement only applies to the current scope.

Since you are never assigning to g_c in the class body, putting the statement there has no effect. The global statement only ever applies to the scope it is used in, never to any nested scopes. See the global statement documentation, which opens with:

The global statement is a declaration which holds for the entire current code block.

Nested functions and classes are not part of the current code block.

I'll insert the obligatory warning against using globals to share changing state here: don't do it, this makes it harder to reason about the state of your code, harder to test, harder to refactor, etc. If you must share a changing singleton state (one value in the whole program) then at least use a class attribute:

class TestClass():    g_c = 0    def run(self):        for i in range(10):            TestClass.g_c = 1            print(TestClass.g_c)  # or print(self.g_c)t = TestClass()t.run()print(TestClass.g_c)

Note how we can still access the same value from the outside, namespaced to the TestClass namespace.


I understand using a global variable is sometimes the most convenient thing to do, especially in cases where usage of class makes the easiest thing so much harder (e.g., multiprocessing). I ran into the same problem with declaring global variables and figured it out with some experiments.

The reason that g_c was not changed by the run function within your class is that the referencing to the global name within g_c was not established precisely within the function. The way Python handles global declaration is in fact quite tricky. The command global g_c has two effects:

  1. Preconditions the entrance of the key "g_c" into the dictionary accessible by the built-in function, globals(). However, the key will not appear in the dictionary until after a value is assigned to it.

  2. (Potentially) alters the way Python looks for the variable g_c within the current method.

The full understanding of (2) is particularly complex. First of all, it only potentially alters, because if no assignment to the name g_c occurs within the method, then Python defaults to searching for it among the globals(). This is actually a fairly common thing, as is the case of referencing within a method modules that are imported all the way at the beginning of the code.

However, if an assignment command occurs anywhere within the method, Python defaults to finding the name g_c within local variables. This is true even when a referencing occurs before an actual assignment, which will lead to the classic error:

UnboundLocalError: local variable 'g_c' referenced before assignment

Now, if the declaration global g_c occurs anywhere within the method, even after any referencing or assignment, then Python defaults to finding the name g_c within global variables. However, if you are feeling experimentative and place the declaration after a reference, you will be rewarded with a warning:

SyntaxWarning: name 'g_c' is used prior to global declaration

If you think about it, the way the global declaration works in Python is clearly woven into and consistent with how Python normally works. It's just when you actually want a global variable to work, the norm becomes annoying.

Here is a code that summarizes what I just said (with a few more observations):

g_c = 0print ("Initial value of g_c: " + str(g_c))print("Variable defined outside of method automatically global? "      + str("g_c" in globals()))class TestClass():    def direct_print(self):        print("Directly printing g_c without declaration or modification: "              + str(g_c))        #Without any local reference to the name        #Python defaults to search for the variable in globals()        #This of course happens for all the module names you import    def mod_without_dec(self):        g_c = 1        #A local assignment without declaring reference to global variable        #makes Python default to access local name        print ("After mod_without_dec, local g_c=" + str(g_c))        print ("After mod_without_dec, global g_c=" + str(globals()["g_c"]))    def mod_with_late_dec(self):        g_c = 2        #Even with a late declaration, the global variable is accessed        #However, a syntax warning will be issued        global g_c        print ("After mod_with_late_dec, local g_c=" + str(g_c))        print ("After mod_with_late_dec, global g_c=" + str(globals()["g_c"]))    def mod_without_dec_error(self):        try:            print("This is g_c" + str(g_c))        except:            print("Error occured while accessing g_c")            #If you try to access g_c without declaring it global            #but within the method you also alter it at some point            #then Python will not search for the name in globals()            #!!!!!Even if the assignment command occurs later!!!!!        g_c = 3    def sound_practice(self):        global g_c        #With correct declaration within the method        #The local name g_c becomes an alias for globals()["g_c"]        g_c = 4        print("In sound_practice, the name g_c points to: " + str(g_c))t = TestClass()t.direct_print()t.mod_without_dec()t.mod_with_late_dec()t.mod_without_dec_error()t.sound_practice()