DEV Community

Cover image for LEGB RULES
Abhinav Pasham
Abhinav Pasham

Posted on

LEGB RULES

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()
Enter fullscreen mode Exit fullscreen mode

There are two variables named x.

Now Python has one question:

Which x should I print?

Should it print:

  • 100 (global)?
  • 50 (inside outer)?
  • 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
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

Output:

Abhinav
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

Output:

Hello
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

Output:

Hyderabad
Enter fullscreen mode Exit fullscreen mode

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))
Enter fullscreen mode Exit fullscreen mode

Output:

3
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

Output:

Local
Enter fullscreen mode Exit fullscreen mode

Search order:

Looking for x

↓

Local → Found

↓

Print "Local"

↓

Stop Searching
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

Output:

NameError: name 'name' is not defined
Enter fullscreen mode Exit fullscreen mode

Python searches:

Local

↓

Enclosing

↓

Global

↓

Built-in

↓

Not Found

↓

NameError
Enter fullscreen mode Exit fullscreen mode

Connection to Closures

Closures work because of the Enclosing scope.

def outer():
    x = 10

    def inner():
        print(x)

    return inner

func = outer()
func()
Enter fullscreen mode Exit fullscreen mode

Output:

10
Enter fullscreen mode Exit fullscreen mode

When inner() looks for x:

Local

↓

Not Found

↓

Enclosing

↓

Found x = 10

↓

Print 10
Enter fullscreen mode Exit fullscreen mode

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)