Menu

Programming Fundamentals

Local and Global Variables

Contents

  1. Scope
  2. Local variables
  3. Global variables
  4. The global statement
  5. Local and global variables with the same name
  6. Benefits of local variables
  7. Using global variables
  8. Local and global constants

Scope describes how far a variable's name reaches through a program: it is the region of code where that name exists, so you can read its value there and, where the language allows, assign a new one. Outside that region the name means nothing to the program, so it cannot be printed, used in a calculation or changed there.

Scope follows from where a variable is created. Every variable in Python is either local or global, and the two words simply describe how far its name reaches.

Local variableGlobal variable
Createdinside a sub programin the main program, outside every sub program
Can be used inthat one sub program onlythe whole program, including every sub program

The two scopes are separate, and that is what makes them useful. The main program cannot see a variable that belongs to a sub program, and one sub program cannot see another's variables, so each sub program keeps its working values to itself.

Scope is a general idea in programming, not something special to Python: any high-level language decides which names are visible where. You apply the idea in Python, where it explains how a program behaves.

Constants have scope in exactly the same way, so a constant can be local to one sub program or global to the whole program.

The program below shows scope in action. The value laps lives and dies with the sub program that made it, so the last line cannot reach it.

A main program box holds global variables usable everywhere, and sub programs with their own locals. laps is local to count_laps, so print(laps) works there but not in another sub program or the main program.

def count_laps():
    laps = 6                 # created here, so its scope is this sub program
    print(laps)

count_laps()
print(laps)                  # the main program is outside the scope of laps

Output:

6
NameError: name 'laps' is not defined (line 6)

Working out a name's scope is what lets you predict what a program will print.

A local variable is a variable that belongs to one sub program. It is created inside that sub program, either by an assignment in its body or by being named in its parameter list. It can be used anywhere inside its own sub program, but nowhere else. In Python, that means a name first assigned inside the indented body of a def block, or listed in the brackets.

How long it lasts

A local variable only exists while its sub program is executing. Once that sub program finishes, the variable is gone. It does not keep its value between calls: each call starts again with a fresh variable. If a sub program finishes with a local variable holding 7, the next call does not begin with 7 — the old variable has gone, so the sub program must create it again before it can be used again.

The main program cannot use it, and neither can any other sub program. Trying to use it outside its own sub program is an error, and the program stops rather than carrying on with a missing value. A parameter is local in the same way: it belongs to that one sub program and cannot be reached from outside. In the program below, cup_size belongs to make_smoothie, so the last line has no such variable to find.

def make_smoothie(fruit):
    cup_size = "large"
    print(fruit, "smoothie in a", cup_size, "cup")

make_smoothie("mango")
print(cup_size)

Output:

mango smoothie in a large cup
NameError: name 'cup_size' is not defined (line 6)

Same name in two sub programs

Two different sub programs may each contain a local variable with the same name. These are completely separate variables held in separate areas of memory, so changing one has no effect at all on the other, even though the code in the two sub programs looks similar. Here, each sub program has its own local badge.

def make_badge(first_name):
    badge = "Visitor: " + first_name
    print(badge)

def make_ticket(last_name):
    badge = "Ticket: " + last_name
    print(badge)

make_badge("Zara")
make_ticket("Okafor")

Output:

Visitor: Zara
Ticket: Okafor

A global variable is a variable created in the main program, outside every sub program definition, usually by an assignment near the top. Because it belongs to the whole program rather than to a single sub program, every part of the program is able to reach it.

Its scope is the whole program, so both the main program and every sub program can read its value. A procedure can access a global variable with no special statement or declaration and with nothing passed in: Python looks for a local variable first, finds none, and uses the global one instead. The variable also stays in existence for as long as the program runs, so its value does not vanish when a sub program finishes.

bottles_collected = 24  # created in the main program

def report_progress():
    print("Bottles so far: " + str(bottles_collected))

report_progress()
print("Final total: " + str(bottles_collected))

Output:

Bottles so far: 24
Final total: 24

The procedure reads bottles_collected directly, and so does the main program, even though nothing was passed in and the procedure contains no declaration of its own.

Why globals help

Globals suit a value that different sections of the program genuinely need: a shared running total, a setting that several sub programs must follow, or a shared target that more than one sub program checks. The value is set in one place, so there is only one copy to keep correct, and any sub program can use it straight away without it being passed in.

Reading a global and changing one are not the same, though: reading needs nothing special, but assigning a new value to a global from inside a sub program needs a global statement naming that variable.

The global statement tells Python that a name used inside a sub program means the single shared global variable, not a new local one. You need one in any sub program that assigns a new value to a global variable.

Writing the statement

Put it at the start of the sub program body, naming the variable it is about.

fuel = 40

def refuel():
    global fuel
    fuel = fuel + 15

refuel()
print(fuel)

Output:

55

Because of global fuel, the assignment inside refuel changes the one global fuel. The new value is still there after the sub program ends, so the main program prints the updated total.

The statement does not give the variable a value — the global already exists, created in the main program. It only says which variable the name refers to here. The line also affects nothing outside the sub program it is written in, so every sub program that assigns to fuel needs its own global line. A sub program that only reads the value needs no statement at all, because Python falls back to the global when there is no local of that name.

Without the statement

Python treats any name assigned inside a sub program as a new local variable. Assigning to it without a global statement therefore creates a separate local with that name, and the global keeps its original value — printing in the main program afterwards shows the value from before the call.

Sub program containsWhat the assignment does
global fuelChanges the shared global; the new value stays after the sub program ends
No global statementCreates a new local variable; the global is unchanged

Reading the name too early

Python decides what a name means by looking at the whole sub program, not just the line it sits on. If the sub program reads the name before the line that assigns to it, and there is no global statement, the program stops with an error: the name is a local variable that has not yet been given a value.

tickets = 12

def print_tickets():
    print(tickets)
    tickets = 0

print_tickets()

Output:

UnboundLocalError: cannot access local variable 'tickets' where it is not associated with a value (line 4)

Sometimes the main program and a sub program both use the same variable name, and the sub program assigns a value to it. Which variable the name means inside the sub program depends on one thing: whether the sub program contains a global statement for that name.

Without a global statement

When the sub program assigns to the name without a global statement, Python creates a new local variable with that name. Every use of the name inside that sub program then refers to the local variable, not the global one. The global variable is left completely alone, so after the sub program ends it still holds its original value, even though the sub program appeared to change it.

bottles = 24

def count_crate():
    bottles = 30
    print("In the crate:", bottles)

count_crate()
print("In the cupboard:", bottles)

Output:

In the crate: 30
In the cupboard: 24

With a global statement

If the sub program starts with global followed by the name, there is only one variable: the shared global. Assigning to the name inside the sub program changes that single variable, so the new value is still there after the sub program ends and the main program prints it.

bottles = 24

def count_crate():
    global bottles
    bottles = 30
    print("In the crate:", bottles)

count_crate()
print("In the cupboard:", bottles)

Output:

In the crate: 30
In the cupboard: 30

Predicting the output

To work out what a program with a name clash prints, trace each use of the name separately. First ask whether a global statement for that name appears at the start of the sub program. If it does, every use inside is the global. If it does not, an assignment inside the sub program makes the name local throughout that sub program, so every use inside is the local. Then follow the values line by line, and for each print statement write down the value and the reason: local or global.

A local variable earns its place because it makes a sub program easier to write, test, reuse and maintain, not just because it keeps a value tidy.

Self-contained, so testable and reusable

A sub program that uses only its own local variables and its parameters is self-contained: the values it needs from the rest of the program arrive as parameters, so it depends on nothing else. That means you can test it on its own, before the rest of the program is written or working, by simply calling it with some values and checking what comes back. It also means you can copy it into another program and call it there without changing a line, because it carries all its working inside itself.

def lap_time(seconds):
    # minutes and extra are local to this function
    minutes = seconds // 60
    extra = seconds % 60
    return str(minutes) + "m " + str(extra) + "s"

print(lap_time(95))
print(lap_time(200))

Output:

1m 35s
3m 20s

Each call passes in a different number of seconds, yet the function needs no other part of the program to do its job. minutes and extra belong to that one function, so a change to a variable called minutes somewhere else in the program could not disturb them.

Nothing is changed by accident

Because no other part of the program can reach a local variable, nothing outside the sub program can alter it behind your back. If a result comes out wrong, the fault must lie inside that single sub program, so you search a few lines instead of the whole program, and the bug is found faster.

Names can be reused and memory is freed

Local variables also let the same name appear in several sub programs without clashing. Each sub program can use the obvious name for its own job, which makes the code easier to read and to maintain later. Finally, the memory a local variable uses is released when the sub program ends, so a program that runs for a long time does not fill memory with values that are already finished with.

A global variable is created in the main program, outside every sub program, so any part of the program can use it. It is the sensible choice when a value really is needed by lots of the program: if several sub programs must know the same setting, or all work on the same running total, going global saves you passing it in over and over, and any sub program can read it without being handed anything. The code stays short and easy to follow.

When a global earns its place

  • A running total that several sub programs add to, such as a cycling club counting up the kilometres ridden by each member.
  • A setting that every sub program must follow, so the whole program behaves consistently.
  • A value that never changes while the program runs but is needed in several places — best written as a global constant.
club_name = "Riverside Runners"   # one setting the whole program follows

def welcome(name):
    print("Welcome to " + club_name + ", " + name)

def cheer(name):
    print(club_name + " cheers for " + name)

welcome("Ada")
cheer("Ada")

Output:

Welcome to Riverside Runners, Ada
Riverside Runners cheers for Ada

The drawbacks

Because a global belongs to the whole program, any part of the program can change it. If it ends up holding the wrong value, there is no easy way to tell which sub program put it there, so the program is harder to debug. It is also harder to maintain, because an edit inside one sub program can affect code written somewhere else entirely. A global lasts from the moment it is created until the program ends, so it occupies memory for the whole run, even while nothing is using it at that moment. Globals are not always a mistake, though — the problem is having many of them.

Keeping globals to a minimum

Pass values into a sub program as parameters and send results back out with return values. The sub program then depends on nothing outside itself, so you can test it in isolation and drop it into a different program without changing a line. Keep globals for the few values genuinely needed everywhere, and write any fixed value as a constant with a name in capitals, such as POSTAGE = 2.75, so the capitals warn everyone that it must not be reassigned.

def lap_total(lap1, lap2):
    return lap1 + lap2

morning = lap_total(48, 51)
evening = lap_total(47, 52)
print("Total seconds: " + str(morning + evening))

Output:

Total seconds: 198

A constant is a named value that is set once and never changed. Constants have scope in exactly the same way as variables: put one at the top level of your program, outside every sub program, and it is global; put one inside a sub program and it is local.

Global constants

A global constant is declared at the top level of your program, outside every sub program, and its name is written in capital letters. Every sub program can read it, so the value is stored in one place only: if the value ever needs to change, you edit one line instead of hunting through the program for every copy.

No global statement is needed to read a global constant inside a sub program. A global statement is only needed when a sub program assigns to a global, and a constant is never assigned to after it is set, so reading works straight away.

PERIOD_MINUTES = 50  # global constant, read by every sub program

def minutes_since_start(periods):
    return periods * PERIOD_MINUTES

def minutes_left(periods_done, total_periods):
    return (total_periods - periods_done) * PERIOD_MINUTES

print(minutes_since_start(3))
print(minutes_left(2, 6))

Output:

150
200

Both sub programs read the same PERIOD_MINUTES, so the length of a period is defined in exactly one place.

Local constants

A local constant belongs to one sub program and nowhere else. You declare it on a line inside that sub program because the fixed value it holds matters only to that routine. Nothing outside can read it, and it disappears when the sub program ends, so the main program cannot use it at all.

def book_slot(people):
    MAX_PER_SLOT = 8  # local constant, only this sub program needs it
    if people <= MAX_PER_SLOT:
        return "Slot booked"
    return "Too many people for one slot"

print(book_slot(4))
print(book_slot(9))

Output:

Slot booked
Too many people for one slot

Python does not enforce constants: writing a name in capitals does not stop a later line assigning a new value to it, so keeping a constant constant is the programmer's job.

Also useful