datarekha
Python Medium Asked at AmazonAsked at GoogleAsked at Microsoft

Explain Python's LEGB scope rule with an example.

The short answer

Python resolves names by searching four scopes in order: Local, Enclosing, Global, then Built-in. The first match wins. Assignment in a scope always creates or modifies a name in that scope unless global or nonlocal overrides this.

How to think about it

What the interviewer is really testing

LEGB is often asked as a warm-up to see if you understand closures and the global/nonlocal keywords. The interesting part is not the acronym — it’s explaining the subtle rule that any assignment inside a function makes Python treat that name as local for the entire function body, even lines above the assignment.

The four scopes, from innermost to outermost

  1. Local — inside the currently executing function.
  2. Enclosing — any outer function scopes (for closures), searched inside-out.
  3. Global — module-level namespace.
  4. Built-in — Python’s built-ins (len, range, print, …).

Python stops at the first scope where the name is found. Reading uses LEGB; writing always targets Local unless you use global or nonlocal.

Step-by-step walkthrough

x = "global"            # G

def outer():
    x = "enclosing"     # E

    def inner():
        x = "local"     # L
        print(x)        # "local"   — L wins

    inner()
    print(x)            # "enclosing" — E is innermost for outer()

outer()
print(x)                # "global"

Each print resolves x starting from its own local scope and working outward.

The classic trap — UnboundLocalError

counter = 0

def increment():
    counter += 1    # UnboundLocalError: counter read before assignment

Python sees the assignment counter += 1 inside the function and decides counter is a local variable — for the whole function. But it has not been assigned yet when the read-side of += executes, so you get UnboundLocalError. The fix:

def increment():
    global counter
    counter += 1

For closures, use nonlocal:

def make_counter():
    count = 0
    def inc():
        nonlocal count
        count += 1
        return count
    return inc

Interactive playground — experiment with all four scopes

The key insight

The rule “any assignment makes the name local for the whole function” is what makes Python predictable. Without it, reading a global before a local assignment would silently return the global value up until the assignment line — an order-dependent surprise. Python’s approach surfaces the bug loudly instead.

Learn it properly Functions

Keep practising

All Python questions

Explore further

Skip to content