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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># ../myproject/main.py
# Define global myList
global myList
myList = []
# Imports
import subfile
# Do something
subfile.stuff()
print(myList[0])
</code>
<code># ../myproject/main.py # Define global myList global myList myList = [] # Imports import subfile # Do something subfile.stuff() print(myList[0]) </code>
# ../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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># ../myproject/subfile.py
# Save "hey" into myList
def stuff():
globals()["myList"].append("hey")
</code>
<code># ../myproject/subfile.py # Save "hey" into myList def stuff(): globals()["myList"].append("hey") </code>
# ../myproject/subfile.py

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

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># ../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])
</code>
<code># ../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]) </code>
# ../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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># ../myproject/subfile.py
# Import globfile
import globfile
# Save "hey" into myList
def stuff():
globfile.myList.append("hey")
</code>
<code># ../myproject/subfile.py # Import globfile import globfile # Save "hey" into myList def stuff(): globfile.myList.append("hey") </code>
# ../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.

2

The problem is you defined myList from main.py, but subfile.py needs to use it. Here is a clean way to solve this problem: move all globals to a file, I call this file settings.py. This file is responsible for defining globals and initializing them:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># settings.py
def init():
global myList
myList = []
</code>
<code># settings.py def init(): global myList myList = [] </code>
# settings.py

def init():
    global myList
    myList = []

Next, your subfile can import globals:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># subfile.py
import settings
def stuff():
settings.myList.append('hey')
</code>
<code># subfile.py import settings def stuff(): settings.myList.append('hey') </code>
# subfile.py

import settings

def stuff():
    settings.myList.append('hey')

Note that subfile does not call init()— that task belongs to main.py:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># main.py
import settings
import subfile
settings.init() # Call only once
subfile.stuff() # Do stuff with global var
print settings.myList[0] # Check the result
</code>
<code># main.py import settings import subfile settings.init() # Call only once subfile.stuff() # Do stuff with global var print settings.myList[0] # Check the result </code>
# main.py

import settings
import subfile

settings.init()          # Call only once
subfile.stuff()         # Do stuff with global var
print settings.myList[0] # Check the result

This way, you achieve your objective while avoid initializing global variables more than once.

12

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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>x = 0 # Default value of the 'x' configuration setting
</code>
<code>x = 0 # Default value of the 'x' configuration setting </code>
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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import config
print (config.x)
</code>
<code>import config print (config.x) </code>
import config
print (config.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.

6

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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># ../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])
</code>
<code># ../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]) </code>
# ../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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># ../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")
</code>
<code># ../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") </code>
# ../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")

3

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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>##test.py:
from pytest import *
print hello_world
</code>
<code>##test.py: from pytest import * print hello_world </code>
##test.py:

from pytest import *

print hello_world

and:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>##pytest.py
hello_world="hello world!"
</code>
<code>##pytest.py hello_world="hello world!" </code>
##pytest.py

hello_world="hello world!"

3

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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># 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
</code>
<code># 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 </code>
# 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

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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># ../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])
</code>
<code># ../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]) </code>
# ../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

1

Namespace nightmares arise when you do from config import mySharedThing. That can’t be stressed enough.

It’s OK to use from in other places.

You can even have a config module that’s totally empty.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># my_config.py
pass
</code>
<code># my_config.py pass </code>
# my_config.py
pass
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># my_other_module.py
import my_config
def doSomething():
print(my_config.mySharedThing.message)
</code>
<code># my_other_module.py import my_config def doSomething(): print(my_config.mySharedThing.message) </code>
# my_other_module.py
import my_config

def doSomething():
    print(my_config.mySharedThing.message)
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># main.py
from dataclasses import dataclass
from my_other_module import doSomething
import my_config
@dataclass
class Thing:
message: str
my_config.mySharedThing = Thing('Hey everybody!')
doSomething()
</code>
<code># main.py from dataclasses import dataclass from my_other_module import doSomething import my_config @dataclass class Thing: message: str my_config.mySharedThing = Thing('Hey everybody!') doSomething() </code>
# main.py
from dataclasses import dataclass
from my_other_module import doSomething
import my_config

@dataclass
class Thing:
    message: str

my_config.mySharedThing = Thing('Hey everybody!')
doSomething()

result:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$ python3 main.py
Hey everybody!
</code>
<code>$ python3 main.py Hey everybody! </code>
$ python3 main.py
Hey everybody!

But using objects you pulled in with from will take you down a path of frustration.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># my_other_module.py
from my_config import mySharedThing
def doSomething():
print(mySharedThing.message)
</code>
<code># my_other_module.py from my_config import mySharedThing def doSomething(): print(mySharedThing.message) </code>
# my_other_module.py
from my_config import mySharedThing

def doSomething():
    print(mySharedThing.message)

result:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$ python3 main.py
ImportError: cannot import name 'mySharedThing' from 'my_config' (my_config.py)
</code>
<code>$ python3 main.py ImportError: cannot import name 'mySharedThing' from 'my_config' (my_config.py) </code>
$ python3 main.py
ImportError: cannot import name 'mySharedThing' from 'my_config' (my_config.py)

And maybe you’ll try to fix it like this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code># my_config.py
mySharedThing = None
</code>
<code># my_config.py mySharedThing = None </code>
# my_config.py
mySharedThing = None

result:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>$ python3 main.py
AttributeError: 'NoneType' object has no attribute 'message'
</code>
<code>$ python3 main.py AttributeError: 'NoneType' object has no attribute 'message' </code>
$ python3 main.py
AttributeError: 'NoneType' object has no attribute 'message'

And then maybe you’ll find this page and try to solve it by adding an init() method.

But the whole problem is the from.

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:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>class My_Globals:
def __init__(self):
self.global1 = "initial_value_1"
self.global2 = "initial_value_2"
...
</code>
<code>class My_Globals: def __init__(self): self.global1 = "initial_value_1" self.global2 = "initial_value_2" ... </code>
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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>global1 = "initial_value_1"
</code>
<code>global1 = "initial_value_1" </code>
global1 = "initial_value_1"

use

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>globals = My_Globals()
</code>
<code>globals = My_Globals() </code>
globals = My_Globals()

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

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>globals.desired_global
</code>
<code>globals.desired_global </code>
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.

Based on above answers and links within I created a new module called global_variables.py:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ==============================================================================
#
# global_variables.py - Global variables shared by all modules.
#
# ==============================================================================
USER = None # User ID, Name, GUID varies by platform
def init():
""" This should only be called once by the main module
Child modules will inherit values. For example if they contain
import global_variables as g
Later on they can reference 'g.USER' to get the user ID.
"""
global USER
import getpass
USER = getpass.getuser()
# End of global_variables.py
</code>
<code>#!/usr/bin/env python # -*- coding: utf-8 -*- # ============================================================================== # # global_variables.py - Global variables shared by all modules. # # ============================================================================== USER = None # User ID, Name, GUID varies by platform def init(): """ This should only be called once by the main module Child modules will inherit values. For example if they contain import global_variables as g Later on they can reference 'g.USER' to get the user ID. """ global USER import getpass USER = getpass.getuser() # End of global_variables.py </code>
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# ==============================================================================
#
#       global_variables.py - Global variables shared by all modules.
#
# ==============================================================================

USER = None                 # User ID, Name, GUID varies by platform

def init():
    """ This should only be called once by the main module
        Child modules will inherit values. For example if they contain
        
            import global_variables as g
            
        Later on they can reference 'g.USER' to get the user ID.
    """
    global USER

    import getpass
    USER = getpass.getuser()

# End of global_variables.py

Then in my main module I use this:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import global_variables as g
g.init()
</code>
<code>import global_variables as g g.init() </code>
import global_variables as g
g.init()

In another child imported module I can use:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<code>import global_variables as g
# hundreds of lines later....
print(g.USER)
</code>
<code>import global_variables as g # hundreds of lines later.... print(g.USER) </code>
import global_variables as g
# hundreds of lines later....
print(g.USER)

I’ve only spent a few minutes testing in two different python multiple-module programs but so far it’s working perfectly.

I saw once somewhere in the internet (sorry, can’t remember where) the following way (that I have been using since then):

  1. Create a file called (for example) variables.py where you declare all your globals, ex:

    variable1=0.0
    variable2= “my text”

  2. call such variables wherever you want (in another files for example):

    variables.variable1= 1 (here assigning 1 to it)

Edit: found an example of it: https://www.edureka.co/community/52900/how-do-i-share-global-variables-across-modules-python

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật