Global and Local Variables
A subroutine can use local variables, formal parameter names, and static member variables declared outside the subroutine.
Try it: Scope: Local, Enclosing, Global, Built-in
How Python looks up a name Local → Enclosing → Global → Built-in, why assigning to a name inside a function makes it local (and raises UnboundLocalError if it is read first), and what global, nonlocal and closures change.
How it works
- Before a function runs, Python marks every name assigned inside it as local to that function, unless it is declared global or nonlocal.
- Reading a name searches the local namespace, then enclosing functions, then the module's globals, then the built-ins; the first hit wins.
- A local name read before it has a value raises UnboundLocalError (Python does not fall back to the global).
- global x makes assignments go to the module namespace; nonlocal x makes them go to the nearest enclosing function.
- A function's local frame disappears when it returns, unless an inner function (a closure) still uses its variables.
Default run (10 steps): Ready: Local shadows global. Every name is looked up Local, then Enclosing, then Global, then Built-in. … Finished. Printed: inside: 99 / outside: 10.
Simplified: The lab's own small Python interpreter runs a fixed, hand-written script (you choose the variant and the values, never the code); nothing is executed as real Python. Every script was run in CPython 3.12 with the same inputs and the lab reproduces its output and error messages. Built-ins shows only the names the script used.
Loading the simulation…
A Name Inside a Subroutine Can Reach Further Than the Subroutine
Read a subroutine and you will see a list of names: some it creates for its own use, some arrive as inputs when it is called, and some refer to things that exist somewhere else in the program. Before you can predict what a subroutine will do, you need to know which of these situations each name falls into. Most of the surprises in beginner code come from one case in particular, where a name used inside a subroutine refers to a variable that was defined outside it and that continues to exist after the subroutine finishes.
What do you think happens?
A subroutine adds 5 to a variable that was declared outside the subroutine. After the subroutine returns, what does the calling code see when it reads that variable?
Reveal answer
The calling code sees the changed value, because the variable exists independently of the subroutine.
A global variable exists independently of the subroutine and is accessible to other parts of the program. Changes a subroutine makes to a global variable can have effects that extend outside that subroutine. The change is not confined to the subroutine's body.
The Three Kinds of Variables a Subroutine Can Use
A subroutine can use three different sorts of variables. Each one has a different origin, and the differences between them determine how far a change can travel.
- Local variable: a variable declared inside the subroutine. It belongs to the subroutine's own body.
- Formal parameter name: the name the subroutine uses for an input it receives when it is called.
- Static member variable declared outside the subroutine: a variable declared elsewhere, in the class that contains the subroutine, which the subroutine is able to use.
The first two kinds are created by the subroutine's own structure: one is written inside its body and the other is named in its input list. The third kind is different. It is created outside the subroutine and it exists independently of the subroutine's body. That difference is what the rest of this article depends on.
Where Each Kind of Variable Lives
The diagram below places the three kinds of variables inside the structures that contain them. Read it from the top down. The class holds the static member variables, and the subroutine holds its own parameters and local variables. The subroutine can reach the class-level names, but those names are not contained by the subroutine. This containment relationship is the simplest way to see why static members behave differently from the other two kinds.
What Makes a Variable Global to a Subroutine
Things change when a subroutine uses a variable that was defined outside it. That variable exists independently of the subroutine and is accessible to other parts of the program as well. Because of this, it is described as global to the subroutine. This is the opposite of a local variable, which is defined inside the subroutine and disappears from the picture once the subroutine's work is done.
The key question for a global variable is not whether the subroutine can see it. The key question is how far beyond the subroutine its influence reaches.
The source describes where a global variable can be used. It can be used throughout the class where it is defined, and in other classes as well, unless it is private. Privacy is therefore the boundary that limits a global's reach: a variable that is not private can be used beyond the class that declares it, while a private one cannot.
Tracing a Global Variable Across a Call
A running total changed by a subroutine
A class declares a static member variable called running total with the value 10. A subroutine adds 5 to running total. The main routine reads running total, calls the subroutine, and then reads running total again. What value does the main routine see the second time?
- 1Identify the variable
running total is declared outside the subroutine, in the class. It is a static member variable, so it is a global to the subroutine and exists independently of the subroutine's body.
- 2Read the value before the call
Before the call, running total holds 10. The main routine sees 10.
- 3Run the subroutine
The subroutine adds 5 to running total. Because the variable is not local, the change is made to the one variable that the rest of the program also uses.
- 4Read the value after the call
The subroutine has returned, but the variable still exists. Its value is now 15, and the main routine sees 15.
The main routine sees 15. The subroutine's change extended outside the subroutine.
The before-and-after view below isolates the one value that matters. The subroutine's effect is visible to the calling code because the variable it changed was never local to the subroutine.
Local Variables Versus Static Lifetime
The contrast between a local variable and a static member variable explains why the static one carries its value forward. A local variable is defined inside the subroutine and disappears once the subroutine's work is done. A static member variable is declared outside the subroutine and exists independently of it, so its value can persist across multiple calls to the subroutine.
| Feature | Local variable | Static member variable declared outside the subroutine |
|---|---|---|
| Where it is declared | Inside the subroutine | Outside the subroutine, in the class |
| Exists independently of the subroutine | No | Yes |
| What happens when the subroutine finishes | It disappears from the picture | It still exists and keeps its value |
| Can its value carry over from one call to the next | No | Yes |
| Can a change to it affect code outside the subroutine | No | Yes |
Local variables and static member variables declared outside a subroutine
Mistakes When Reasoning About Global Variables
Common mistake Assuming every name used inside a subroutine is local to it
What it looks likeA subroutine updates running total and the reader assumes the change disappears when the subroutine ends.
Why it failsrunning total was declared outside the subroutine. It exists independently of the subroutine's body and continues to exist after the call.
Do this insteadFor each name, first ask where it was declared. Only names declared inside the subroutine are local to it.
Common mistake Assuming a change to a global variable stays inside the subroutine
What it looks likeAfter the call, the caller reads the variable and expects its original value.
Why it failsChanges a subroutine makes to a global variable can have effects that extend outside that subroutine.
Do this insteadTrace the variable's value before and after the call and read it from the calling code's point of view.
Common mistake Forgetting that privacy limits where a global can be used
What it looks likeA static member variable is assumed to be usable by any other class.
Why it failsA global variable can be used in other classes unless it is private. A private one does not have that reach.
Do this insteadCheck whether the variable is marked private before deciding how far its influence can reach.
Practising the Trace
A static member variable named counter starts at 0. A subroutine called once adds 1 to counter. The subroutine is then called a second time, and the calling code reads counter afterward. Predict the value the calling code reads, and explain which of the three kinds of variables counter is in the subroutine.
Hints
- Ask first where counter was declared. If it was declared outside the subroutine, it exists independently of the subroutine.
- Track the value through each call in order, starting from 0.
- A static member variable can keep its value from one call to the next.
Key Takeaways on Scope and Reach
- 1A subroutine can use three kinds of variables: local variables declared inside it, formal parameter names for its inputs, and static member variables declared outside it.
- 2A static member variable declared outside the subroutine is global to the subroutine. It exists independently of the subroutine's body and is accessible to other parts of the program.
- 3A change a subroutine makes to a global variable can be seen by code outside the subroutine, so the important question is how far the change reaches.
- 4Global variables can be used throughout their class and in other classes unless they are private.
At a glance
- A subroutine can use local variables, formal parameter names, and static member variables declared outside the subroutine.
- A global variable exists independently of the subroutine and is accessible to other parts of the program.
- Changes a subroutine makes to a global variable can extend outside that subroutine and be seen by calling code.
- Global variables can be used throughout their class and in other classes unless they are private.