Introduction
When you write Python code, variables can exist in different scopes — for example, inside a function, inside another nested function, or at the top of your script (global scope).
Understanding how to define and modify global and nonlocal variables is essential for writing clean, predictable code.
Global Variables
A global variable is defined outside any function or class and can be accessed from anywhere in the file.
By default, Python treats variables assigned inside a function as local to that function.
If you want to modify a global variable inside a function, you must declare it as global.
Example: Defining and Using a Global Variable
1 2 3 4 5 6 7 8 9 10 11 12 | # Global variable counter = 0 def increment(): global counter # Declare that we want to use the global 'counter' counter += 1 print("Inside function:", counter) increment() increment() print("Outside function:", counter) |
Output:
1 2 3 | Inside function: 1 Inside function: 2 Outside function: 2 |
Without global, you’ll get an error
If you try to modify a global variable inside a function without the global keyword:
1 2 3 4 5 6 7 | counter = 0 def increment(): counter += 1 # UnboundLocalError print(counter) increment() |
Error:
1 | UnboundLocalError: local variable 'counter' referenced before assignment |
Python assumes counter is local, so it complains because there’s no prior assignment in the local scope.
Nonlocal Variables
A nonlocal variable allows you to modify a variable in the nearest enclosing scope (but not the global scope).
This is mainly used in nested functions — functions defined inside another function.
Example: Using a Nonlocal Variable
1 2 3 4 5 6 7 8 9 10 11 12 | def outer(): x = 10 def inner(): nonlocal x # Access the 'x' defined in 'outer' x += 5 print("Inside inner:", x) inner() print("Inside outer:", x) outer() |
Output:
1 2 | Inside inner: 15 Inside outer: 15 |
Here:
xis not global, but belongs toouter().- By using
nonlocal,inner()modifiesxfrom the enclosing scope.
Without nonlocal, modification fails
1 2 3 4 5 6 7 8 9 10 | def outer(): x = 10 def inner(): x += 5 # UnboundLocalError print(x) inner() outer() |
You’ll get:
1 | UnboundLocalError: local variable 'x' referenced before assignment |
Python thinks you’re trying to assign to a new local variable x inside inner().
Comparison Table
| Feature | Scope Affected | Used In | Typical Use Case |
|---|---|---|---|
global |
Module level | Any function | Modify global variable |
nonlocal |
Enclosing func | Nested functions | Modify outer (non-global) variable |
Summary
- Variables defined inside a function are local by default.
- Use
globalto modify a global variable inside a function. - Use
nonlocalto modify a variable in an enclosing (non-global) scope. - Avoid overusing
global— prefer returning values or using classes for cleaner design.
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 | x = 100 def outer(): x = 50 def inner(): global x x += 10 print("Inner:", x) inner() print("Outer:", x) outer() print("Global:", x) |
Output
1 2 3 | Inner: 110 Outer: 50 Global: 110 |
When to Define a Global Variable Outside a Function in Python
When Global Variables Are Useful
A global variable defined outside any function is useful when:
You need shared state or constants
For example, a configuration value, path, or constant that doesn’t change during execution:
1 2 | BASE_URL = "https://api.nasa.gov" VERSION = 1.0 |
These are global variables — and functions can read them directly.
You want several functions to access the same variable
1 2 3 4 5 6 7 8 9 | counter = 0 def increment(): global counter counter += 1 def reset(): global counter counter = 0 |
Here, both functions work with the same counter defined globally.
You’re writing small scripts or prototypes
For small, single-file programs, global variables can simplify your code.
When to Avoid Global Variables
Global variables become a problem when:
- Your codebase grows and many functions modify them — making debugging harder.
- You lose track of where a variable is changed.
- Functions rely on hidden state (making them less predictable and harder to reuse).
In those cases, it’s better to use:
- Function parameters and return values, or
- Classes to encapsulate state.
Example: Good vs. Bad Practice
Bad: Global variable modified everywhere
1 2 3 4 5 6 7 8 9 10 11 12 13 | count = 0 def add(): global count count += 1 def multiply(): global count count *= 2 add() multiply() print(count) |
Here, the behavior depends on the order of function calls — risky for large programs.
Better: Return values or use classes
1 2 3 4 5 6 7 8 9 10 | def add(count): return count + 1 def multiply(count): return count * 2 count = 0 count = add(count) count = multiply(count) print(count) |
or using a class:
1 2 3 4 5 6 7 8 9 10 11 12 | class Counter: def __init__(self): self.value = 0 def add(self): self.value += 1 def multiply(self): self.value *= 2 counter = Counter() counter.add() counter.multiply() print(counter.value) |
In Summary
| Situation | Should you use a global variable? | Alternative |
|---|---|---|
| Defining constants or read-only config | Yes | — |
| Small scripts or one-off analyses | Okay | — |
| Large applications with shared mutable state | Usually no | Use classes, return values, or modules |
| Need to share values between functions | Sometimes | Pass as parameters |
References
| Links | Site |
|---|---|
| https://docs.python.org/3/tutorial/classes.html#python-scopes-and-namespaces | Python Docs — Scopes and Namespaces |
| https://docs.python.org/3/reference/simple_stmts.html#the-global-statement | Python Docs — global Statement Reference |
| https://docs.python.org/3/reference/simple_stmts.html#the-nonlocal-statement | Python Docs — nonlocal Statement Reference |
| https://peps.python.org/pep-3104/ | PEP 3104 — Access to Names in Outer Scopes (nonlocal) |
| https://realpython.com/python-scope-legb-rule/ | Real Python — Understanding Python Scope (LEGB Rule) |
