Python
programming
variables
modules
coding tips

How to create module-wide variables in Python?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In Python, a module-wide variable is simply a name defined at the top level of a module file. That makes it part of the module namespace, so code in the same module can read it directly and other modules can access it through an import.

The Basic Pattern

Define the variable outside any function or class:

python
# settings.py
app_name = "demo"
counter = 0

Those names now live in the module namespace. Code in the same module can read them directly:

python
print(app_name)

Another module can import them:

python
import settings

print(settings.app_name)

That is the core mechanism. There is no special syntax required just to create a module-wide variable.

Modifying a Module Variable Inside a Function

Reading a module variable inside a function is easy. Modifying it requires global if you want to rebind the module-level name from inside that function.

python
1counter = 0
2
3def increment():
4    global counter
5    counter += 1

Without global, Python assumes counter inside the function is a local variable assignment target, which leads to errors if you try to read and write it as though it were the module-level name.

Access From Other Modules

If another file imports the module, it can access the module-wide variable through the module object:

python
# config.py
mode = "development"
python
1# main.py
2import config
3
4print(config.mode)
5config.mode = "production"
6print(config.mode)

This works because modules are objects, and their top-level names become attributes on that module object.

Import Style Matters

There is an important difference between:

python
import config

and:

python
from config import mode

With import config, you keep a reference to the module object. If config.mode changes later, reading config.mode reflects the current module state.

With from config import mode, you bind the current value to a local name in the importing module. Reassigning config.mode later does not automatically update that separate local binding.

That distinction surprises people when they try to share mutable module state across files.

Constants Versus Mutable State

Module-wide variables are often best for:

  • constants,
  • configuration defaults,
  • small caches,
  • and module-level singletons.

For example:

python
API_BASE_URL = "https://example.com/api"
TIMEOUT_SECONDS = 30

This is clear and common.

For mutable shared state, use more care. A module-level counter or cache can be fine in a small program, but large systems often become harder to reason about when many functions mutate global module state.

A Cleaner Mutable Pattern

If you need shared mutable state, one option is to keep it inside a dedicated object:

python
1class State:
2    def __init__(self):
3        self.counter = 0
4
5state = State()

Then:

python
def increment():
    state.counter += 1

This avoids global rebinding and makes the state container more explicit.

Threading and Process Caveats

Module-wide variables are only "global" within one Python process. They are not automatically shared across:

  • multiple processes,
  • separate worker interpreters,
  • or distributed systems.

Even within one process, threads can race on mutable module state if you update it without synchronization.

So if the module variable represents important shared data in concurrent code, you may need locks or a different state-management strategy.

When Not to Use Module Globals

Avoid module-wide mutable state when:

  • test isolation matters,
  • many modules depend on hidden shared state,
  • or the state should be configurable per request, per user, or per task.

In those cases, function arguments, dependency injection, or instance-based design usually scales better.

Common Pitfalls

The biggest pitfall is forgetting that rebinding a module variable inside a function needs the global keyword.

Another mistake is using from module import name and then expecting that local binding to reflect later reassignments made inside the original module.

Developers also often overuse module-wide mutable state when a class, argument, or explicit config object would make dependencies clearer.

Finally, remember that module-wide variables are process-local. They are not shared automatically across multiple Python processes.

Summary

  • A module-wide variable is just a top-level name defined in a module file.
  • Use global only when rebinding that module-level name inside a function.
  • 'import module and from module import name behave differently for shared state.'
  • Module globals are fine for constants and some small shared state.
  • For larger mutable systems, explicit state objects are often easier to maintain.

Course illustration
Course illustration

All Rights Reserved.