[python] Using global variables between files?

I'm bit confused about how the global variables work. I have a large project, with around 50 files, and I need to define global variables for all those files.

What I did was define them in my projects main.py file, as following:

# ../myproject/main.py

# Define global myList
global myList
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

I'm trying to use myList in subfile.py, as following

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
    globals()["myList"].append("hey")

An other way I tried, but didn't work either

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

And inside subfile.py I had this:

# ../myproject/subfile.py

# Import globfile
import globfile

# Save "hey" into myList
def stuff():
    globfile.myList.append("hey")

But again, it didn't work. How should I implement this? I understand that it cannot work like that, when the two files don't really know each other (well subfile doesn't know main), but I can't think of how to do it, without using io writing or pickle, which I don't want to do.

This question is related to python share globals

The answer is


You can think of Python global variables as "module" variables - and as such they are much more useful than the traditional "global variables" from C.

A global variable is actually defined in a module's __dict__ and can be accessed from outside that module as a module attribute.

So, in your example:

# ../myproject/main.py

# Define global myList
# global myList  - there is no "global" declaration at module level. Just inside
# function and methods
myList = []

# Imports
import subfile

# Do something
subfile.stuff()
print(myList[0])

And:

# ../myproject/subfile.py

# Save "hey" into myList
def stuff():
     # You have to make the module main available for the 
     # code here.
     # Placing the import inside the function body will
     # usually avoid import cycles - 
     # unless you happen to call this function from 
     # either main or subfile's body (i.e. not from inside a function or method)
     import main
     main.mylist.append("hey")

Hai Vu answer works great, just one comment:

In case you are using the global in other module and you want to set the global dynamically, pay attention to import the other modules after you set the global variables, for example:

# settings.py
def init(arg):
    global myList
    myList = []
    mylist.append(arg)


# subfile.py
import settings

def print():
    settings.myList[0]


# main.py
import settings
settings.init("1st")     # global init before used in other imported modules
                         # Or else they will be undefined

import subfile    
subfile.print()          # global usage

Using from your_file import * should fix your problems. It defines everything so that it is globally available (with the exception of local variables in the imports of course).

for example:

##test.py:

from pytest import *

print hello_world

and:

##pytest.py

hello_world="hello world!"

See Python's document on sharing global variables across modules:

The canonical way to share information across modules within a single program is to create a special module (often called config or cfg).

config.py:

x = 0   # Default value of the 'x' configuration setting

Import the config module in all modules of your application; the module then becomes available as a global name.

main.py:

import config
print (config.x)

or

from config import x
print (x)

In general, don’t use from modulename import *. Doing so clutters the importer’s namespace, and makes it much harder for linters to detect undefined names.


I just came across this post and thought of posting my solution, just in case of anyone being in the same situation as me, where there are quite some files in the developed program, and you don't have the time to think through the whole import sequence of your modules (if you didn't think of that properly right from the start, such as I did).

In such cases, in the script where you initiate your global(s), simply code a class which says like:

class My_Globals:
  def __init__(self):
    self.global1 = "initial_value_1"
    self.global2 = "initial_value_2"
    ...

and then use, instead of the line in the script where you initiated your globals, instead of

global1 = "initial_value_1"

use

globals = My_Globals()

I was then able to retrieve / change the values of any of these globals via

globals.desired_global

in any script, and these changes were automatically also applied to all the other scripts using them. All worked now, by using the exact same import statements which previously failed, due to the problems mentioned in this post / discussion here. I simply thought of global object's properties being changing dynamically without the need of considering / changing any import logic, in comparison to simple importing of global variables, and that definitely was the quickest and easiest (for later access) approach to solve this kind of problem for me.


Your 2nd attempt will work perfectly, and is actually a really good way to handle variable names that you want to have available globally. But you have a name error in the last line. Here is how it should be:

# ../myproject/main.py

# Import globfile    
import globfile

# Save myList into globfile
globfile.myList = []

# Import subfile
import subfile

# Do something
subfile.stuff()
print(globfile.myList[0])

See the last line? myList is an attr of globfile, not subfile. This will work as you want.

Mike