Python puzzler: the import statement and global variables

Recently I’ve joined the BOS team in helping develop the next generation of the survey software. This time round were using Django (a Python-based web framework), PostgreSQL and Cassandra (a NoSQL database).

Although I’ve dabbled with Python briefly in the past this is my first substantial Python-based project. As a new Python developer I hit rather confusing bug in our code recently that concerned the Python import statement and global variables. It’s an interesting little oddity that I thought would be worth writing about.

Say we have a module ( which contains a global dictionary object which needs to be initialised in a lazy fashion:

DICT = {} # create a 'global' var
def init_dict():
    global DICT # make sure we are not referencing a local reference
    DICT = {'a' : '1', 'b' : 2} # reset or reassign variable
    print 'Dict initalized to length:',len(DICT) # everything looks good


Now we have another module ( referencing this first:

from mod1 import DICT, init_dict
print 'Initial length of dict:',len(DICT)
init_dict() # initialise the DICT variable
print 'New length of dict:',len(DICT)

Seems valid. So what output would you expect when we run this code?

Huh? We confirm the initial state, initialised the DICT variable, re-read it’s contents, and still get the initial state. So what should we do to correct this?

import mod1
print 'Initial length of dict:',len(mod1.DICT)
print 'New length of dict:',len(mod1.DICT)




It looks similar but this time round we import the module itself  rather then the DICT directly, and reference DICT via the module reference. After much web searching I finally found the answer – that global variables are confined to their module’s namespace (i.e. they are not shared between modules despite the use of the term ‘global’). Actually I only found this out after I copied the text of this blog post into a new stackoverflow question and it automatically pointed me at a previous answer, but as it stumped me for quite a while I thought it is worth highlighting to others.