Global Variables and the Global Keyword
If you want to assign a value to a name defined at the top level of the program (i.e. not inside any kind of scope such as functions or classes), then you have to tell Python that the name is not local, but it is global . We do this using the global statement. It is impossible to assign a value to a variable defined outside a function without the global statement.
Why Scope Matters: The Problem
When you write a Python program, variables live in different scopes. A variable defined at the top level of your program (outside any function) is global. A variable created inside a function is local to that function. This separation exists for good reasons: it prevents accidental changes to important values, and it lets different functions use the same variable names without interfering with each other. But this also creates a puzzle: what happens when you try to change a global variable from inside a function?
What do you think happens?
You have a global variable called count set to 0. Inside a function, you write count = count + 1. Will this modify the global count, or will it create a new local variable?
Reveal answer
Answer: It will create a new local variable called count and leave the global unchanged
Python sees the assignment count = count + 1 and decides that count is a local variable for the entire function. When you try to read count on the right side of the assignment, Python looks for a local count first, finds none, and raises an UnboundLocalError. Even if the read succeeded, the assignment would create a local copy, not modify the global.
How Python Decides: Local or Global?
Python uses a simple rule to determine whether a name is local or global: it scans the entire function body before the function runs. If it sees an assignment to a name anywhere in the function, that name is treated as local throughout the entire function. This happens at parse time, not at runtime. So even if the assignment comes after a read, the read will still look for a local variable.
You can read a global variable inside a function without any special keyword, as long as you never assign to it in that function. But the moment you assign to a name, Python marks it as local for the entire function.
Reading vs. Writing: The Asymmetry
There is a crucial asymmetry between reading and writing global variables. Reading a global variable inside a function works automatically: Python searches the local scope, finds nothing, then searches the global scope and finds it. Writing (assigning) to a global variable does not work automatically. If you assign to a name inside a function, Python treats that name as local for the entire function, and the assignment creates or modifies a local copy, not the global.
This asymmetry exists because Python wants to prevent accidental modification of global state. By requiring an explicit global declaration, you signal your intent to modify a global variable, making the code clearer and safer.
The Global Keyword: Declaring Intent
To assign to a global variable from inside a function, you must use the global statement. Place it at the beginning of your function (or anywhere before you assign to that variable). The global statement tells Python: this name refers to the global variable, not a local one. When you assign to it, you are modifying the global variable, not creating a local copy.
You can declare multiple global variables in a single statement using a comma-separated list: global x, y, z. Each name listed will be treated as global throughout the function.
Tracing Execution: Without Global
Let's trace what happens when you try to modify a global variable without the global keyword. This is the most common mistake beginners make.
Attempting to modify a global without the global keyword
You have a global variable score = 0. Inside a function, you try to add 10 to it with score = score + 10. What happens?
Python scans the function: Before the function runs, Python scans the entire function body and sees the assignment score = score + 10. It marks score as local for the entire function.
Function is called: When you call the function, Python enters it and begins executing.
Right side of assignment is evaluated: Python tries to evaluate score + 10. It looks for score in the local scope, finds nothing, and raises UnboundLocalError: local variable 'score' referenced before assignment.
Function crashes: The function never reaches the assignment. The global score remains 0, unchanged.
UnboundLocalError is raised. The global variable is not modified.
Tracing Execution: With Global
Now let's trace the same scenario, but with the global keyword. The outcome is completely different.
Modifying a global with the global keyword
You have a global variable score = 0. Inside a function, you declare global score and then write score = score + 10. What happens?
Python scans the function: Python scans the function and sees global score. This tells Python that score refers to the global variable, not a local one.
Function is called: When you call the function, Python enters it and begins executing.
Right side of assignment is evaluated: Python evaluates score + 10. It looks for score in the global scope (because of the global declaration), finds it with value 0, and computes 0 + 10 = 10.
Assignment happens: Python assigns 10 to the global score. The global variable is now 10.
Function completes: The function returns. The global score remains 10 after the function exits.
The global score is successfully modified to 10.
Common Mistakes
Forgetting the global keyword and trying to modify a global variable
Python sees the assignment count = count + 1 and marks count as local. When it tries to evaluate count + 1, it looks for a local count, finds none, and raises UnboundLocalError.
Fix:
Add global count at the start of the function: def increment(): global count count = count + 1Using global when you only need to read a global variable
The global keyword is unnecessary here. You can read a global variable without declaring it global. Using global when you don't need it is not wrong, but it is misleading and suggests you plan to modify the variable.
Fix:
Remove the global statement: def show_total(): print(total)Placing the global statement after you use the variable
While Python may accept this, it is confusing and poor practice. The global statement should appear at the beginning of the function so readers immediately understand that x is global.
Fix:
Move global to the top: def modify(): global x print(x) x = 10Thinking global makes a variable accessible everywhere
This is not wrong, but it creates code that is hard to follow. The global keyword declares that a name refers to the global scope, but it does not make the variable more accessible—it just clarifies intent. Relying on global variables makes code harder to debug.
Fix:
Minimize global variable use. Pass values as function parameters and return results instead.
Why Avoid Global Variables?
The source material emphasizes that while you can use global variables, you should avoid them. Global variables make code harder to understand and maintain. When you read a function that uses a global variable, you must search elsewhere in the program to find where that variable is defined and modified. This creates hidden dependencies that make bugs harder to find.
Instead of using global variables, pass values as function parameters and return results. This makes the function's inputs and outputs explicit, and it makes your code easier to test and reuse.
In professional codebases, global variables are generally avoided except for configuration constants (like API keys or settings that truly never change). Even then, these are often placed in a dedicated configuration module and imported where needed, rather than modified with the global keyword.
When Global Is Appropriate
There are rare cases where using the global keyword is appropriate. One example is a simple script where you need to maintain state across function calls and passing parameters would be cumbersome. Another is when you are working with a global configuration or flag that genuinely needs to be accessible and modifiable from multiple functions. However, even in these cases, consider whether a class or a configuration module would be a better design.
Practice: Predict the Outcome
For each code snippet below, predict what will happen when the function is called. Will the global variable be modified, will an error occur, or will a local variable be created?
Hints
- Remember: if you assign to a name anywhere in the function, Python treats it as local unless you use the global keyword.
- Reading a global variable without assigning to it does not require the global keyword.
- The global statement must appear before you use the variable for the declaration to take effect.
What do you think happens?
Snippet 1: What happens here? value = 10 def change_value(): value = value + 5 change_value() print(value)
Reveal answer
Answer: Raises UnboundLocalError before printing
Python sees the assignment value = value + 5 and marks value as local. When it tries to evaluate value + 5, it looks for a local value, finds none, and raises UnboundLocalError. The function never completes, so print(value) is never reached.
What do you think happens?
Snippet 2: What happens here? value = 10 def change_value(): global value value = value + 5 change_value() print(value)
Reveal answer
Answer: Prints 15
The global statement tells Python that value refers to the global variable. When the function assigns value = value + 5, it modifies the global value from 10 to 15. After the function returns, print(value) prints 15.
What do you think happens?
Snippet 3: What happens here? value = 10 def read_value(): print(value) read_value() print(value)
Reveal answer
Answer: Prints 10 twice
There is no assignment to value inside read_value(), so Python does not mark it as local. When read_value() executes print(value), Python searches the local scope, finds nothing, then searches the global scope and finds value = 10. The function prints 10, and then the global print(value) also prints 10.
Summary
- Python distinguishes between global scope (top level of the program) and local scope (inside a function). Variables in each scope are separate.
- You can read a global variable inside a function without any special keyword, as long as you never assign to it in that function.
- If you assign to a name anywhere in a function, Python treats that name as local for the entire function, creating a local copy instead of modifying the global.
- To modify a global variable from inside a function, use the global statement at the beginning of the function. This tells Python that the name refers to the global variable, not a local one.
- You can declare multiple global variables in one statement: global x, y, z.
- Avoid using global variables when possible. Instead, pass values as parameters and return results. This makes code clearer and easier to maintain.
Key Takeaways
- Python treats any name that is assigned inside a function as local, unless you explicitly declare it global.
- Reading a global variable requires no special keyword, but writing to it requires the global statement.
- The global keyword must appear before you use the variable and signals that you intend to modify the global variable, not create a local copy.
- Global variables should be used sparingly; passing parameters and returning values is usually a better design choice.
- Understanding scope prevents UnboundLocalError and makes your code's intent clear to other readers.