Global Variables

intermediate20 min

Learning objectives

  • Explain how global variables differ from local variables
  • Evaluate their advantages and disadvantages
  • Apply good programming practice when designing modular software

Learn

AQA 4.1.1.14 — Global variables

Retrieval: the previous lesson established that local variables are created and destroyed inside a single function call. A global variable is the opposite: declared outside every function, at the top level of a program, so it exists for as long as the program runs and can be read from any function.

MAX_ATTEMPTS = 3   # global - declared outside any function

def show_limit():
    print(f"You have {MAX_ATTEMPTS} attempts.")   # reading a global works with no special syntax

show_limit()

Common mistake

Reading a global variable inside a function needs nothing special — but modifying one does. Without the global keyword, assigning to a name inside a function always creates a brand new local variable with that name, silently leaving the real global variable untouched:

score = 0   # global

def add_point():
    score = score + 1   # UnboundLocalError! Python treats this "score" as local
                          # because it's assigned to inside the function - but a
                          # local variable can't be read before it's assigned

add_point()

Fixed version, using global to explicitly say "I mean the global score, not a new local one":

score = 0

def add_point():
    global score
    score = score + 1

add_point()
add_point()
print(score)   # 2

Advantages and disadvantages

Advantage: any function can access shared state without it being explicitly passed around as a parameter — occasionally convenient for small scripts or genuinely program-wide settings (like MAX_ATTEMPTS above). Disadvantage: any function can silently change that shared state, which makes larger programs far harder to reason about, test and debug — a bug caused by global state could originate from any function in the program, not just the one where the symptom appears. This is precisely why well-designed modular programs prefer parameters and return values (the previous two lessons) over global variables wherever possible.

Worked example — good vs poor practice

# Poor practice: relies on a global variable being modified inside a function
total = 0

def add_to_total(amount):
    global total
    total += amount

add_to_total(10)
add_to_total(5)
print(total)   # 15 - works, but any function anywhere could silently change "total"

# Good practice: no global state - the function's effect is explicit
def add(current_total, amount):
    return current_total + amount

total2 = 0
total2 = add(total2, 10)
total2 = add(total2, 5)
print(total2)   # 15 - identical result, but add() can't affect anything it wasn't given

Both versions produce the same output — the difference is that add()'s behaviour is entirely visible from its parameters and return value, while add_to_total()'s behaviour depends on hidden global state.

Challenge

Refactor this poorly-designed program so it uses parameters and return values instead of a global variable, then confirm it still produces the same output:

balance = 100

def withdraw(amount):
    global balance
    balance -= amount

withdraw(30)
withdraw(20)
print(balance)

Looking ahead: Sequence 4 (Fundamental Data Structures) starts using arrays and other structures to hold much larger collections of data — the same discipline of preferring explicit parameters and return values over hidden shared state applies just as much there as it does here.

Practise

Apply what you've just learned in the Coding Lab.

Open Coding Lab

Test yourself

Check your understanding with exam-style questions.

Go to Exam Practice
Log in to track this lesson on your progress dashboard.
Log in