Guide Python Intermediate

6.8 Variable Scope

Local, global, and enclosing scope in Python, the global and nonlocal keywords, and the LEGB rule Python uses to resolve any name.

3 min read
flowchart TD B["Built-in\nlen, print, range, ... — always available"] Gs["Global\nnames at module level"] E["Enclosing\nnames in an outer (enclosing) function"] L["Local\nnames inside the current function"] L --> E --> Gs --> B

Python searches Local → Enclosing → Global → Built-in, stopping at the first match.

Local Scope

What Is It?

Names created inside a function exist only within that function call, and disappear once it returns.

Why Is It Used?

Keeps a function’s internal working variables from leaking into or colliding with the rest of the program.

def greet():
    message = "Hello"    # local to greet()
    print(message)

>>> greet()
Hello
>>> message                # not accessible outside the function
Traceback (most recent call last):
NameError: name 'message' is not defined

Global Scope

Names defined at module (top) level are accessible for reading from anywhere in that module, including inside functions — but writing to them from inside a function requires the global keyword.

The global Keyword

What Is It?

Tells Python that an assignment inside a function should modify the module-level (global) variable, instead of creating a new local one. Without it, any assignment to that name inside the function creates a separate local variable — the exact cause of the UnboundLocalError bug covered in 6.12 Common Mistakes.

count = 0

def increment():
    global count
    count += 1

>>> increment(); increment()
>>> count
2

nonlocal

The equivalent of global, but for reaching one level up into an enclosing function’s scope (not all the way to module level) — used in nested functions/closures.

def outer():
    x = "enclosing"
    def inner():
        nonlocal x
        x = "modified by inner"
    inner()
    print(x)

>>> outer()
modified by inner

The LEGB Rule

The order Python searches when resolving a name: Local → Enclosing → Global → Built-in, stopping at the first scope where the name is found. This explains exactly which variable a given name refers to in any nested-function situation.

Quick Interview Answer

“Python resolves any name using the LEGB rule: Local scope first, then any Enclosing function’s scope, then module-level Global scope, then Built-ins — stopping at the first match. Reading a global from inside a function works without any keyword, but writing to it requires global, or Python creates a new local variable instead. nonlocal is the same idea one level up, for reaching into an enclosing function’s scope from a nested closure rather than all the way to module level.”

Common Mistakes

  • Forgetting global when trying to reassign a module-level variable inside a function — the assignment silently creates a new local variable instead, and the global is left untouched.
  • Confusing global and nonlocalglobal always reaches module level; nonlocal reaches exactly one enclosing function scope, not all the way up.
  • Assuming Python has block scope (like if/for) — it doesn’t; see 6.12 Common Mistakes for the “incorrect scope” bug this causes.

Add More Questions to This Guide

Know a question that should be here? Share it and help the community!

Open Google Form