I'm working on a Python project with multiple files, and I need a way to share certain state variables (like a logged_in flag or config_settings) across all of them. I tried declaring a variable as global in one file and importing it into another, but changes made in one module don't seem to reflect in the others. Is there a "canonical" way to handle shared state in Python without creating a mess of circular imports? Should I use a dedicated config.py file, or is there a better pattern involving classes or singletons?
3 answers
The most common and "Pythonic" way to share variables is to create a dedicated module (often named config.py or settings.py). In Python, modules are only initialized once—the first time they are imported—and then cached. This means all other modules importing config.py will reference the exact same module object.If you use from config import shared_value, you create a local copy of that reference in your current module. If shared_value is an immutable type (like an integer or string), changing it in your local file won't affect the config module. Always use import config and access via config.variable to ensure you are modifying the shared instance.
While the config.py method is great for simple scripts, have you considered using a Singleton class or a simple dictionary? If you wrap your globals in a class, you can add validation logic or "getter/setter" methods to track when and why a global variable is being changed—isn't that much safer for larger Software Development projects?
If you're dealing with sensitive data like API keys, you shouldn't use a Python module for globals at all. Use environment variables with os.getenv() or a .env file. It's much cleaner for deployment.
Absolutely, Susan. For configuration that changes between environments (Dev vs. Prod), environment variables are the gold standard in modern cloud development.
William makes a vital point about debugging. In larger systems, global variables can become "spaghetti" where you don't know who changed what. A common middle-ground is to use a dictionary: shared_state = {'user': None, 'theme': 'dark'}. Since dictionaries are mutable, even if you do from config import shared_state, modifying its keys will reflect across all modules. However, I still prefer Dorothy's import config approach because it's the most explicit and follows the "Namespaces are one honking great idea" rule from the Zen of Python!