Python Scope
Learn how Python decides where variables can be accessed, how local and global variables work, and how the LEGB rule helps Python find names.
What You Will Learn
By the end of this lesson, you will understand how Python manages variable names and how scope affects the way functions access data.
- Understand local and global scope.
- Explain the LEGB name-resolution rule.
- Work with nested functions and enclosing scope.
-
Understand the
globalkeyword. -
Understand the
nonlocalkeyword. - Avoid common variable-scope mistakes.
What Is Scope?
In Python, scope refers to the region of a program where a variable or name can be accessed.
A variable does not automatically exist everywhere in your program. Python determines where a name is available based on where it was created.
A variable created inside a function normally belongs to that function. Code outside the function cannot directly access it.
def greet():
name = "Ali"
print(name)
greet()
# print(name) # NameError
Ali
The variable name exists inside
greet(). It is therefore a
local variable.
Why Scope Matters
Scope helps keep programs organized by controlling which parts of a program can access particular names.
Without scope, variables created for one task could accidentally interfere with variables used by another part of a program.
Use local variables whenever data only belongs to one function. This makes functions easier to understand, test, and reuse.
Local Scope
A variable created inside a function normally has local scope.
def calculate_total():
price = 100
tax = 15
total = price + tax
print(total)
calculate_total()
115
The variables price, tax,
and total belong to the function.
Once the function finishes, its local variables are no longer directly available from outside that function.
Global Scope
A variable created outside all functions belongs to the global scope of the module.
company = "PyLearn"
def show_company():
print(company)
show_company()
print(company)
PyLearn PyLearn
A function can normally read a global variable if it does not define a local variable with the same name.
Local vs Global Variables
name = "Global Ali"
def greet():
name = "Local Ahmed"
print(name)
greet()
print(name)
Local Ahmed Global Ali
The two variables have the same name but belong to different scopes.
Creating name inside
greet() does not replace the
global name.
The LEGB Rule
When Python sees a variable name, it searches for that name using the LEGB rule.
Local → Enclosing → Global → Built-in
1. Local
Python first looks inside the current function.
2. Enclosing
If the current function is nested inside another function, Python looks in the surrounding function.
3. Global
Python then checks the module-level global scope.
4. Built-in
Finally, Python checks names provided by Python itself,
such as len(), print(),
and sum().
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print(x)
inner()
outer()
local
Python finds the local variable first, so it stops searching there.
Enclosing Scope
Enclosing scope exists when one function is defined inside another function.
def outer():
message = "Hello from outer"
def inner():
print(message)
inner()
outer()
Hello from outer
inner() does not have its own
message, so Python searches the enclosing
outer() scope.
Built-in Scope
Python provides many built-in names that are available without importing a module.
numbers = [10, 20, 30]
print(len(numbers))
print(sum(numbers))
print(max(numbers))
print(min(numbers))
3 60 30 10
Functions such as len(),
sum(), max(), and
min() are built-in names.
Do not unnecessarily create variables such as
list, str,
sum, or len.
Nested Functions
A function defined inside another function is called a nested function.
def calculator():
def add(a, b):
return a + b
result = add(10, 5)
print(result)
calculator()
15
The add() function is only available
inside calculator().
The global Keyword
By default, assigning a value to a variable inside a function creates a local variable.
The global keyword tells Python that the
assignment should modify the module-level variable.
counter = 0
def increase():
global counter
counter += 1
increase()
increase()
increase()
print(counter)
3
Although global is useful in some
situations, excessive use can make programs
harder to understand and maintain.
The nonlocal Keyword
The nonlocal keyword is used inside a
nested function when you want to modify a variable
belonging to the nearest enclosing function scope.
def counter():
count = 0
def increase():
nonlocal count
count += 1
return count
print(increase())
print(increase())
print(increase())
counter()
1 2 3
global targets module-level
variables, while nonlocal targets
a variable in an enclosing function.
Reading vs Modifying Variables
A function can usually read a global variable without
using global.
tax_rate = 0.15
def calculate_tax(price):
return price * tax_rate
print(calculate_tax(100))
15.0
But if you assign to that name inside the function,
Python treats it as local unless you explicitly declare
it as global.
Reading a global variable and assigning to a global variable are different operations.
Scope with Loops and Blocks
Python's if, for, and
while statements do not create a separate
local scope in the same way that functions do.
for number in range(3):
message = number
print(message)
2
The variable message remains accessible
after the loop because the loop does not create a
function-level scope.
Functions create local scopes. Ordinary
if, for, and
while blocks do not work the same
way.
Function Parameters and Scope
Function parameters are local variables belonging to the function call.
def greet(name):
message = f"Hello, {name}"
print(message)
greet("Ali")
# print(name) # NameError
The parameter name exists within the
function's local scope.
This helps functions safely work with their own inputs without automatically creating global variables.
Real-World Examples
Example 1 — Application Configuration
APP_NAME = "PyLearn"
MAX_USERS = 100
def show_config():
print(APP_NAME)
print(MAX_USERS)
show_config()
PyLearn 100
Example 2 — Sales Calculation
def calculate_sale(price, quantity):
subtotal = price * quantity
discount = subtotal * 0.10
final_price = subtotal - discount
return final_price
print(calculate_sale(2000, 3))
5400.0
The calculation variables are local because they are only needed while the function performs its work.
Example 3 — Counter with Enclosing Scope
def create_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter = create_counter()
print(counter())
print(counter())
print(counter())
1 2 3
This is a practical example of how an inner function can remember and modify a value from its enclosing function.
Common Scope Mistakes
Mistake 1 — Expecting Local Variables Outside
def create_user():
username = "Ali"
create_user()
print(username)
This causes a NameError because
username belongs to the function's local
scope.
Mistake 2 — Forgetting global
score = 0
def add_score():
score += 10
add_score()
Python treats score as a local variable
because the function assigns to it.
If modifying the module-level variable is genuinely
intended, use global score.
Mistake 3 — Using Too Many Globals
Large programs become difficult to maintain when many functions depend on and modify shared global variables.
Prefer function parameters, return values, objects, and well-designed data structures instead of relying heavily on global state.
Mistake 4 — Shadowing Built-in Names
list = [1, 2, 3]
print(list("Python"))
The variable named list hides Python's
built-in list() function.
Practice Exercises
Try solving these exercises before looking for a solution.
Exercise 1 — Local Variable
Create a function called show_name()
that creates a local variable named
name and prints it.
Exercise 2 — Global Variable
Create a global variable called
company. Write a function that prints
it.
Exercise 3 — LEGB
Create nested functions containing variables with the same name. Predict which value Python prints.
Exercise 4 — global
Create a global counter and a function that
increases it by one using global.
Exercise 5 — nonlocal
Create an outer function containing
count = 0 and an inner function that
increments it using nonlocal.
Exercise 6 — Scope with Loops
Create a for loop and define a variable
inside it. Print the variable after the loop.
Observe what happens.
Exercise 7 — Parameters
Write a function that accepts a user's name as a parameter and explain why the parameter has local scope.
Challenge — Smart Counter
Build a reusable counter using an enclosing variable
and nonlocal.
Your Task
Create a function named
create_counter().
It should return another function that increases the counter every time it is called.
The expected behavior is:
counter = create_counter()
print(counter())
print(counter())
print(counter())
print(counter())
1 2 3 4
The inner function needs to modify a variable belonging to the outer function. Which keyword should you use?
Quick Quiz
What does scope describe?
What is the first letter in LEGB?
Where is a normal function variable created?
Which keyword allows a function to modify a global variable?
Which keyword modifies a variable in an enclosing function?
Which scope contains functions such as
len() and print()?
Do ordinary for loops create a
function-like local scope?
What is the recommended approach for most temporary function data?
Lesson Summary
Scope determines where Python variables and names can be accessed.
- Local scope belongs to the current function.
- Global scope belongs to the module-level environment.
- Enclosing scope appears with nested functions.
- Built-in scope contains Python's built-in names.
- Python searches names using the LEGB rule.
-
globalallows a function to modify a module-level variable. -
nonlocalallows a nested function to modify a variable from an enclosing function. - Function parameters are local variables.
-
Ordinary
if,for, andwhileblocks do not create function-like local scopes. - Prefer local variables and clear function interfaces instead of excessive global state.
Understanding scope is essential for writing predictable Python functions. Once you understand LEGB, local variables, enclosing variables, and global variables, many previously confusing Python errors become much easier to understand.
You've finished Python Scope!
Mark this lesson complete when you are comfortable
with local scope, global scope, LEGB,
global, and nonlocal.