W3docs

Global Variables in Python

Learn how Python global variables work, how to modify them with the global keyword, avoid UnboundLocalError pitfalls, and when to use alternatives.

Global variables in Python are variables declared outside of any function. They live for the full lifetime of the program and can be read from anywhere — but modifying them inside a function requires the global keyword. This page covers how global variables work, the pitfalls to avoid, and when to reach for better alternatives.

What Are Global Variables?

A global variable is created at the module (top-level) scope — outside of any function or class. Any code in the same module can read it without any special declaration.

python— editable, runs on the server

Python uses the LEGB rule to resolve names: it searches Local → Enclosing → Global → Built-in scopes in that order. A global variable sits at the "G" level, so every function can find it after exhausting its own local and enclosing scopes. See Python Scope for a full explanation of all four levels.

Reading vs. Modifying Global Variables

Reading a global variable (always works)

By default, a function can read any global variable without any special syntax:

language = "Python"

def print_language():
    print(language)  # reads the global

print_language()  # Output: Python

The global keyword — required for modification

If you try to assign to a variable inside a function, Python creates a new local variable instead of updating the global one. To modify the global, you must declare it with the global keyword:

counter = 0

def increment():
    global counter   # tell Python we mean the global 'counter'
    counter += 1
    print("Counter:", counter)

increment()  # Output: Counter: 1
increment()  # Output: Counter: 2
print(counter)  # Output: 2

Without global counter, the line counter += 1 would raise an UnboundLocalError because Python would try to read a local variable called counter before it was assigned.

The UnboundLocalError Pitfall

This is the most common mistake with global variables. The moment Python sees any assignment to a name inside a function, it treats that name as local throughout the entire function — even lines before the assignment:

x = 10

def broken():
    print(x)   # ERROR — Python sees the assignment below and marks x as local
    x = 20

broken()
# UnboundLocalError: local variable 'x' referenced before assignment

Fix it by adding global x at the top of the function if you genuinely need to modify the global, or by renaming the local variable if you want an independent copy.

Variable Shadowing

Assigning to a name inside a function without the global keyword creates a local variable that shadows the global — the global is not changed:

count = 100

def show_count():
    count = 5   # local variable — shadows the global 'count'
    print("Inside function:", count)   # 5

show_count()
print("Outside function:", count)  # 100 — global is unchanged

Shadowing is not an error, but it can be confusing. Use distinct names to make the intent obvious.

global Inside Nested Functions

If you need to reach a module-level global from an inner (nested) function, use global — not nonlocal. nonlocal only reaches the immediately enclosing function's scope, not the module level:

total = 0

def outer():
    def inner():
        global total   # reaches module scope
        total += 10
    inner()

outer()
outer()
print("total:", total)  # Output: total: 20

Compare this with nonlocal, which modifies the enclosing function's variable but leaves the module-level global untouched:

x = "global"

def outer():
    x = "outer"
    def inner():
        nonlocal x   # modifies outer()'s x, not the module-level x
        x = "inner"
    inner()
    print("outer x after inner():", x)  # inner

outer()
print("global x after outer():", x)   # global — unchanged

For a deeper look at nonlocal, see Python Scope.

Module-Level Constants — The Good Use Case

The most legitimate use of module-level globals is for constants — values that are set once and never changed at runtime. By convention, write them in UPPER_SNAKE_CASE:

MAX_RETRIES = 3
DEFAULT_TIMEOUT = 30

def connect(host, retries=MAX_RETRIES, timeout=DEFAULT_TIMEOUT):
    print(f"Connecting to {host} with {retries} retries, timeout={timeout}s")

connect("db.example.com")
# Output: Connecting to db.example.com with 3 retries, timeout=30s

Constants never need the global keyword because you only read them, never reassign.

Best Practices

1. Prefer function arguments and return values

Passing data through function signatures makes code easier to test and reason about. This pure function is simpler than using a mutable global counter:

def increment(counter):
    return counter + 1

counter = 0
counter = increment(counter)
counter = increment(counter)
print("counter:", counter)  # Output: counter: 2

2. Reserve globals for true module-wide constants

Use globals for values that are genuinely fixed for the entire run of the program (MAX_CONNECTIONS, APP_VERSION, configuration loaded once at startup). Avoid mutable globals that change over time.

3. Use descriptive, UPPER_SNAKE_CASE names for constants

A name like MAX_RETRIES is immediately recognizable as a module constant. A name like r is not.

4. Initialize before use

Declare all global variables at the top of the module, before any functions that use them. This prevents NameError if a function is called before the variable would otherwise be defined.

5. Be careful with threads

If multiple threads call functions that modify the same global variable, you get a race condition. Protect shared mutable state with a threading.Lock, or redesign to avoid shared state altogether. See Python Variables for a broader overview of variable types in Python.

Summary

SituationWhat to do
Read a global inside a functionNothing special needed
Modify a global inside a functionAdd global <name> at the top of the function
Modify an enclosing function's variableUse nonlocal <name>
Share a fixed value across many functionsDeclare a module-level constant in UPPER_SNAKE_CASE
Share mutable state between functionsPrefer function arguments and return values

Practice

Practice
In Python, what are the properties of Global Variables?
In Python, what are the properties of Global Variables?
Was this page helpful?