How to Set Global Variables in Python Functions

To set global variables in Python functions, write global name at the top of the function, then assign to name. Without that line, any assignment inside the function creates a new local variable and the global stays the same:

count = 0

def add_one():
    global count
    count += 1

Every example below ran on Python 3.12.5 from the Command Prompt, and the outputs are copied straight from those runs.

You’ll see how global works, why leaving it out raises an error, when you don’t need it at all, how nonlocal differs, and the safer way to share settings between modules.

How to set a global variable inside a function with the global keyword

Here’s a small order tracker. Two module-level variables hold the running count and revenue, and one function updates both. A single global statement can list several names, separated by commas:

orders_today = 0
revenue = 0.0

def record_order(amount):
    global orders_today, revenue      # rebind the module-level names
    orders_today += 1
    revenue += amount

record_order(49.99)
record_order(120.00)
record_order(15.25)
print(f"Orders: {orders_today}")
print(f"Revenue: ${revenue:,.2f}")

Output:

Orders: 3
Revenue: $185.24
Command Prompt output of a Python function that uses the global keyword to update an order count and revenue total
After three calls, the global order count is 3 and the revenue total adds up the three amounts.

The global line doesn’t create or copy anything. It tells Python that inside this function, orders_today and revenue mean the names at module level, so += changes those.

If you only need to read a value, or hand one back to the caller, you don’t need global; that side is covered in accessing variables outside a function in Python.

What happens if you change a global variable without the global keyword?

Python decides whether a name is local when it compiles the function, not when the line runs. Any assignment, including +=, makes the name local for the whole function body. So this fails on the first call:

visits = 0

def track_visit():
    visits += 1          # assignment makes 'visits' local to this function
    return visits

track_visit()

Output:

Traceback (most recent call last):
  File "C:\pyguides\track_visit.py", line 7, in <module>
    track_visit()
  File "C:\pyguides\track_visit.py", line 4, in track_visit
    visits += 1          # assignment makes 'visits' local to this function
    ^^^^^^
UnboundLocalError: cannot access local variable 'visits' where it is not associated with a value
Command Prompt traceback showing UnboundLocalError when a Python function increments a global variable without the global keyword
The += line reads the local visits before it has a value, so Python raises UnboundLocalError.

The fix is one line: add global visits as the first statement of track_visit(). I see this error more than any other scope bug in code reviews.

For other ways this same error shows up, like a variable set only inside an if branch, read fixing UnboundLocalError: local variable referenced before assignment.

When you don’t need global: mutating a global list or dict

global is about rebinding a name, meaning making it point to a new object. Calling a method that changes an existing object, like list.append() or dict[key] = value, doesn’t rebind anything, so it works without the keyword:

cart = ["coffee"]
discount = 0.00

def add_item(item):
    cart.append(item)        # mutating the object: no global needed

def replace_cart(items):
    cart = items             # new LOCAL name; the global list is untouched

def set_discount(value):
    global discount
    discount = value         # rebinding the global name

add_item("bagel")
replace_cart(["tea"])
set_discount(2.50)
print("cart:", cart)
print(f"discount: ${discount:.2f}")

Output:

cart: ['coffee', 'bagel']
discount: $2.50

add_item() changed the shared list, but replace_cart() only made a local cart that vanished when the function returned. set_discount() needed global because it assigns a brand-new value.

The full lookup order Python follows (local, enclosing, global, built-in) is explained in my guide to Python variable scope.

Create a new global variable from inside a function

A name listed in global doesn’t have to exist yet. The assignment inside the function creates it at module level, which you can confirm with globals(), the dictionary of the module’s global names:

def load_settings():
    global STORE_STATE, SALES_TAX
    STORE_STATE = "TX"           # these names did not exist before the call
    SALES_TAX = 0.0625

print("before:", "SALES_TAX" in globals())
load_settings()
print("after: ", "SALES_TAX" in globals())
print(f"{STORE_STATE} sales tax on $80.00: ${80.00 * SALES_TAX:.2f}")

Output:

before: False
after:  True
TX sales tax on $80.00: $5.00

This works, but the variable only exists after the function has run. If anything reads SALES_TAX before load_settings() is called, you’ll get a NameError. I’d rather define the name at the top of the module with a default value.

Upper-case names like SALES_TAX are the usual signal for module constants; Python naming conventions has the rest of the rules.

nonlocal vs global in nested Python functions

Inside a nested function, there’s a third place a name can live: the enclosing function. nonlocal rebinds a name there, and global still skips straight to module level:

total = 0

def make_counter():
    count = 0
    def bump():
        nonlocal count       # the 'count' in make_counter
        global total         # the module-level 'total'
        count += 1
        total += 1
        return count
    return bump

a = make_counter()
b = make_counter()
print("a:", a(), a())     # a's own count: 1, then 2
print("b:", b())          # b starts again from 1
print("total:", total)    # shared by both counters

Output:

a: 1 2
b: 1
total: 3
Command Prompt output comparing Python nonlocal and global in a nested counter function
Each counter keeps its own nonlocal count, while the global total is shared by both.

Counter a was called twice and b once, so each has its own count, but total saw all three calls. nonlocal also refuses to work at module level; it needs an enclosing function that already defines the name.

If nested functions are new to you, start with calling a function within a function in Python.

Share global settings across Python modules with a config module

Python’s “global” really means module-level. There’s no program-wide scope, so the usual pattern is a small config.py that other files import:

# config.py - shared settings for the whole app
TAX_RATE = 0.0625
CURRENCY = "USD"

Then any module can read it, and a function can change a setting for everyone by assigning to the module attribute:

import config
from config import TAX_RATE      # copies the value into THIS module

def set_tax(rate):
    config.TAX_RATE = rate       # change the setting for every module

set_tax(0.0825)
print("config.TAX_RATE:", config.TAX_RATE)
print("TAX_RATE copy:  ", TAX_RATE)
print(f"Tax on $200.00: ${200 * config.TAX_RATE:.2f} {config.CURRENCY}")

Output:

config.TAX_RATE: 0.0825
TAX_RATE copy:   0.0625
Tax on $200.00: $16.50 USD
Command Prompt output of a Python config module where config.TAX_RATE changes but a from-import copy keeps the old value
config.TAX_RATE shows the new rate, while the name brought in with from config import still holds the old one.

That’s the pitfall: from config import TAX_RATE creates a separate name in your module that points to the old value. Always write config.TAX_RATE when the value can change at runtime.

Note that set_tax() didn’t need global, because it sets an attribute on the module object. If your config file sits in another folder, see importing from a parent directory in Python.

Rules and pitfalls of the Python global statement

The global line has to come before any use of the name in that function. Put it after an assignment and the file won’t even compile:

code = """
limit = 5
def raise_limit():
    limit = 10
    global limit
"""
try:
    compile(code, "settings.py", "exec")
except SyntaxError as err:
    print("SyntaxError:", err.msg)

Output:

SyntaxError: name 'limit' is assigned to before global declaration

A few more rules to keep in mind:

  • global at module level is allowed but does nothing; the names are already global there.
  • A function parameter can’t also be declared global; that’s a SyntaxError too.
  • Each function needs its own global line. Declaring it in one function doesn’t affect another.
  • Threads share globals, so two threads updating the same counter can lose updates without a lock.

Should you use global variables? Cleaner alternatives

Globals make a function depend on hidden state, which makes it harder to test and reuse. For most code, I pass values in and return the new value instead:

def record_order(state, amount):
    """Take the state in, hand the new state back. No globals."""
    return {"orders": state["orders"] + 1,
            "revenue": round(state["revenue"] + amount, 2)}

state = {"orders": 0, "revenue": 0.0}
for amount in (49.99, 120.00, 15.25):
    state = record_order(state, amount)
print(state)

Output:

{'orders': 3, 'revenue': 185.24}

Same result as the first example, but nothing outside the function changes behind your back. Returning several values at once is covered in returning multiple values from a function in Python.

For settings with sensible defaults, a parameter often beats a global; see Python functions with optional arguments. When state really belongs together, a class with attributes is the tidier home.

global vs nonlocal vs module attribute compared

ApproachChangesExample
global xModule-level name, from any functionglobal count; count += 1
nonlocal xName in the enclosing functionnonlocal count; count += 1
Mutate the objectContents of a global list or dictcart.append(item)
module.x = ...Setting shared by every importerconfig.TAX_RATE = 0.0825
Return a valueNothing global (preferred)state = update(state)

Want to keep going with functions? These pick up where this one stops:

Frequently asked questions

How do I change a global variable inside a Python function?

Add global name as the first line of the function, then assign to name. The change is visible everywhere in the module.

Do I need the global keyword just to read a global variable?

No. Reading a global works without it. You only need global when the function assigns a new value to the name.

Why do I get UnboundLocalError when I update a global?

Any assignment, including +=, makes the name local for the whole function. Declare it with global first.

What’s the difference between global and nonlocal?

global rebinds a module-level name. nonlocal rebinds a name in the nearest enclosing function.

How do I share a global variable between modules?

Put it in a module such as config.py, import config, and read or set config.NAME. Avoid from config import NAME for values that change.

Where is the global statement documented?

See the global statement in the Python language reference.