When you start programming in Python, one of the core concepts you’ll encounter early on is variable scope. Understanding variable scope is essential because it defines where variables exist and how they can be accessed within your code. This knowledge helps you write clean, bug-free programs and makes debugging a lot easier.
In this lesson, we will explore what variable scope means, the different types of scopes in Python, and how Python resolves variable names. We will also go through practical examples to solidify your understanding.
What is Variable Scope?
Variable scope refers to the context or region of your program where a variable is accessible. Depending on where and how a variable is declared, Python decides if you can use that variable or not at a particular point in the code.
Imagine your program as a large office building. Each room represents a scope. Variables declared in one room are like documents kept in that room — they are only accessible to people inside that same room, unless explicitly shared outside.
💡 Why does scope matter?
It helps prevent accidental changes to variables and keeps your program organized. Scopes also allow you to reuse variable names in different parts of your program without conflicts.
The Four Scopes in Python (LEGB Rule)
Python follows the LEGB rule to resolve variable names:
- Local — Variables defined inside the current function.
- Enclosing — Variables in the local scope of any enclosing functions (functions that wrap the current function).
- Global — Variables defined at the top-level of a module or declared global using the
globalkeyword. - Built-in — Names preassigned in the built-in Python module (like
print(),len(), etc.)
Python looks for a variable name in this order: first local, then enclosing, then global, and finally built-in. It uses the first match it finds.

Exploring Each Scope with Practical Examples
Local Scope
A variable declared inside a function is local to that function. It cannot be accessed outside the function.
📌 Deep Dive: Local Variables
def greet():
message = "Hello, world!" # local variable
print(message)
greet()
print(message) # trying to access outside the function
Notice that the variable message is accessible inside greet() but raises an error outside because its scope is local to that function.
Enclosing Scope (Nested Functions)
When you have functions defined inside other functions, variables in the outer function are in the enclosing scope for the inner function.
📌 Deep Dive: Enclosing Scope with Nested Functions
PYTHON
def outer():
outer_var = "I'm in the outer function"
def inner():
print(outer_var) # accessing enclosing scope variable
inner()
outer()
OutputI'm in the outer function
Here, inner() can access outer_var even though it’s not defined inside inner(), but in the enclosing scope of outer().
Global Scope
Variables defined at the top-level of a script or module are global variables and can be accessed anywhere inside that module, including functions — unless shadowed by a local variable.
📌 Deep Dive: Global Variables
PYTHON
name = "Alice" # global variable
def greet():
print(f"Hello, {name}!")
greet()
print(name)
OutputHello, Alice!
Alice
Both inside and outside the function, the global variable name is accessible.
Modifying Global Variables Inside Functions
By default, if you assign a value to a variable inside a function, Python treats it as local, even if there is a global variable with the same name. To modify a global variable inside a function, you must declare it as global.
📌 Deep Dive: Using global Keyword
PYTHON
counter = 0 # global variable
def increment():
global counter
counter += 1
print(counter)
increment()
print(counter)
Output0
1
Without the global declaration, counter += 1 would raise an error because Python thinks counter is a local variable that’s being used before assignment.
⚠️ Common Pitfall: Accidental Shadowing
Be careful not to unintentionally create local variables with the same names as global ones, which can lead to bugs that are hard to trace.
Built-in Scope
Python has a set of built-in names and functions that are always available. If you use a variable name that is also a built-in name, Python will prioritize your local or global variable first, then the built-in one only if no other definition is found.
💡 Best Practice
Avoid naming your variables after built-in functions (like list, str, max) to prevent confusion and bugs.
How Python Resolves Variable Names: An Example
Let's combine all scopes in one example to see how Python finds variable values.
📌 Deep Dive: LEGB in Action
PYTHON
x = "global x" # global
def outer():
x = "enclosing x" # enclosing
def inner():
x = "local x" # local
print(x) # prints local
inner()
print(x) # prints enclosing
outer()
print(x) # prints global
Outputlocal x
enclosing x
global x
Notice that inner() prints the local x, outer() prints its own x (enclosing), and the global x is printed last outside the functions.
Global vs Local Variables: Summary Table
Comparison of Global and Local Variables
Aspect Global Variable Local Variable
Defined Outside all functions (top-level) Inside a function
Scope Accessible anywhere in the module Accessible only inside the function
Modification inside function Use global keyword Direct assignment
Lifespan Exists as long as program runs Exists only while function runs
Common use Shared data/configuration Temporary values and parameters
Best Practices for Managing Variable Scope
- Minimize global variables: Use them sparingly to avoid unintended side effects.
- Use function parameters and return values: Pass data explicitly rather than relying on globals.
- Keep variable names descriptive: This reduces the chance of shadowing and improves readability.
- Use nested functions carefully: Understand the enclosing scope to avoid confusion.
- Use
nonlocal keyword when needed: To modify variables in the enclosing scope (covered briefly below).
Quick Note on the nonlocal Keyword
Besides global, Python offers nonlocal to modify variables in an enclosing (non-global) scope inside nested functions.
📌 Deep Dive: nonlocal Usage
PYTHON
def outer():
count = 0
def inner():
nonlocal count
count += 1
print(count)
inner()
inner()
outer()
Output1
2
Without nonlocal, the assignment count += 1 inside inner() would create a new local variable instead of modifying the variable in outer().
⚠️ Remember: nonlocal only affects variables in enclosing function scopes, not globals.
Summary
Understanding variable scope in Python is fundamental for writing effective and bug-free code. Remember the LEGB rule:
- Local: Variables inside the current function.
- Enclosing: Variables in the outer functions.
- Global: Variables defined at the module level.
- Built-in: Python's predefined names.
Variable scope controls accessibility and lifetime of variables. Use global and nonlocal keywords carefully to modify variables outside the local scope. Proper scope management leads to cleaner, more maintainable code.
💡 Key Takeaway:
Always be conscious of where your variables are declared and accessed. This awareness will help you prevent common bugs and write clear Python code.
Quick Knowledge Check
Test what you just learned
Question 1 of 2
What is the correct order Python looks for a variable name according to the LEGB rule?
Question 2 of 2
Which keyword allows you to modify a variable defined in an enclosing (non-global) scope from inside a nested function?
0/2Loading results...