Search code examples
pythonscriptingnamespacesglobal-variablesscope

Global Variables between scripts


I have a python project with few scripts run by .sh shell files.

I have a config file which defines a dictionary to be used across scripts.

config.py

name_dict = dict()

file1.py

from config import *
..
..

## I have that reads tries to load the dump file that will contain the json values. 

name_dict = json.load(open(dict_file))

##This file - file1.py calls another function fun() in file2.py, iteratively 3/4 times. 
..    
file2.fun(args)
print "Length of dict in file1.py : %d " %len(name_dict) // Always Zero ??? Considers name_dict as local variable.

In file2 - file2.py, I have defined name_dict with global keyword.fun() uses and updates the name_dict and finally I print the length of the dict at the start and I find it to be updated.

def fun(args)    
    global name_dict
    print "Length of dict file2.py(start): %d " %len(name_dict)
    ..
    ..
    print "Length of dict file2.py(end): %d " %len(name_dict)

Every time after the control returns from file2, In file1.py I print the value of name_dict and it is zero. But, in the next call to fun() -> the print statement still prints the global value(length) of name_dict()

But in file1.py it is always zero. My guess is it is treated as a local variable. How do I fix this ?


Solution

  • Python does not have global variables. The variables are all enclosed in modules, hence you could say that what you defined are module-level variables.

    In order to modify a module variable you must assign it to the module:

    #file1.py
    import config
    
    config.name_dict = json.load(...)
    

    Doing:

    from config import *
    
    name_dict = json.load(...)
    

    simple creates a new name_dict, module-level variable and assigns a new object to it, it does not change anything in the config module.

    Also note that the global statement tells python that the given name should not be treated as a local variable. For example:

    >>> x = 0
    >>> def function():
    ...     x = 1
    ... 
    >>> function()
    >>> x
    0
    >>> def function():
    ...     global x
    ...     x = 1
    ... 
    >>> function()
    >>> x
    1
    

    It does not mean that you can access x from other modules. Also it is useful only when assigning to a variable:

    >>> x = 0
    >>> def function():
    ...     return x + 1
    ... 
    >>> function()
    1
    >>> def function():
    ...     global x
    ...     return x + 1
    ... 
    >>> function()
    1
    

    As you can see you can reference the module-level x without saying that it is a global. What you cannot do is doing x = something and change the module-level variable value.