LEGB RULES IN PYTHON
INTRODUCTION
While learning Python, I often heard people say, "Python follows the LEGB rule while searching for variables." At first, I memorized what LEGB stood for, but I never understood why Python needs this rule or how it actually searches for variables. Once I understood the search order, it became much easier to understand concepts like closures, nested functions, and decorators.
In this article, I'll explain the LEGB rule in a simple way.
What You Will Learn
- Why Python needs the LEGB rule
- The four scopes in Python
- How Python searches for variables
- What happens when a variable isn't found
- How LEGB is related to closures
Prerequisites
Before learning LEGB, you should understand:
- Variables
- Functions
- Nested functions
- Variable scope
The Problem
Imagine you write a program like this:
x = 100
def outer():
x = 50
def inner():
print(x)
inner()
outer()
There are two variables named x.
Now Python has one question:
Which
xshould I print?
Should it print:
-
100(global)? -
50(insideouter)? - Or something else?
Without a rule, Python wouldn't know which variable to use.
To solve this problem, Python follows the LEGB Rule.
What is LEGB?
LEGB is the order Python follows while searching for a variable.
It stands for:
- L → Local
- E → Enclosing
- G → Global
- B → Built-in
Python checks these scopes one by one until it finds the variable.
How Python Searches
Whenever Python sees a variable, it searches like this:
Need variable
↓
Local Scope
↓
Found?
↓
Yes → Use it
↓
No
↓
Enclosing Scope
↓
Found?
↓
Yes → Use it
↓
No
↓
Global Scope
↓
Found?
↓
Yes → Use it
↓
No
↓
Built-in Scope
↓
Found?
↓
Yes → Use it
↓
No
↓
NameError
Python stops searching as soon as it finds the variable.
Understanding Each Scope
1. Local Scope (L)
The local scope contains variables created inside the current function.
def greet():
name = "Abhinav"
print(name)
greet()
Output:
Abhinav
Here, Python first looks inside greet() and finds name.
2. Enclosing Scope (E)
The enclosing scope exists when one function is inside another function.
def outer():
message = "Hello"
def inner():
print(message)
inner()
outer()
Output:
Hello
message isn't inside inner(), so Python checks the enclosing function (outer) and finds it there.
3. Global Scope (G)
Variables created outside all functions belong to the global scope.
city = "Hyderabad"
def show():
print(city)
show()
Output:
Hyderabad
Python doesn't find city inside show(), so it checks the global scope.
4. Built-in Scope (B)
Python already provides many built-in functions.
numbers = [3, 7, 2]
print(len(numbers))
Output:
3
We never created len(), but Python finds it in the built-in scope.
Complete Example
x = "Global"
def outer():
x = "Enclosing"
def inner():
x = "Local"
print(x)
inner()
outer()
Output:
Local
Search order:
Looking for x
↓
Local → Found
↓
Print "Local"
↓
Stop Searching
Python never checks the enclosing or global scopes because it already found the variable locally.
What Happens If Python Doesn't Find the Variable?
def greet():
print(name)
greet()
Output:
NameError: name 'name' is not defined
Python searches:
Local
↓
Enclosing
↓
Global
↓
Built-in
↓
Not Found
↓
NameError
Connection to Closures
Closures work because of the Enclosing scope.
def outer():
x = 10
def inner():
print(x)
return inner
func = outer()
func()
Output:
10
When inner() looks for x:
Local
↓
Not Found
↓
Enclosing
↓
Found x = 10
↓
Print 10
Closures rely on Python remembering the enclosing scope even after the outer function has finished executing.
Advantages of the LEGB Rule
- Removes ambiguity when multiple variables have the same name.
- Makes variable lookup predictable.
- Supports nested functions.
- Enables closures.
- Forms the foundation for decorators.
- Helps organize code by separating local and global data.
Conclusion
The LEGB rule is simply Python's variable lookup mechanism. Whenever a variable is used, Python searches in this order:
Local → Enclosing → Global → Built-in
As soon as the variable is found, Python stops searching. If it isn't found in any of these scopes, Python raises a NameError.
Understanding LEGB is important because many advanced Python concepts—including nested functions, closures, and decorators—depend on it.
Top comments (0)