Courses/Python Mastery/Module 7: Functions
Module 7 · Lesson 415 minBeginner

Scope: Local vs Global (LEGB in 5 Minutes)

Lesson goal
Understand where variables live and why names clash or vanish.

Scope: Local vs Global (LEGB in 5 Minutes)

Where a variable is *created* decides where it can be *seen*. That's scope — and understanding it explains a whole family of "why is my variable not defined / why did it not change" bugs in one go.

The two levels you need today

code
total = 0                    # GLOBAL — created at file level

def add_points(points):
    bonus = 10               # LOCAL — created inside the function
    total = total + points   # 💥 UnboundLocalError!
  • Global variables live at the file's top level — visible *everywhere*, including inside functions (readable!)
  • Local variables live inside a function — born when the function runs, destroyed when it ends
  • Reading globals works; writing them doesn't

    code
    site_name = "Tech With Galvan"      # global
    
    def show_site():
        print(site_name)                # ✅ reading a global — works
    
    show_site()                          # Tech With Galvan

    Reading is fine. But assignment creates a NEW local variable:

    code
    count = 0                    # global
    
    def increase():
        count = 100              # ⚠️ this CREATES A LOCAL count — global untouched!
    
    increase()
    print(count)                 # 0 — the global never changed

    Python's rule: assign to a name inside a function, and Python treats it as local — unless you explicitly say otherwise. That's why total = total + points crashed earlier: Python sees the assignment, decides total is local, then discovers you're reading it before the local exists.

    The fix #1: don't reassign — use return (the professional way)

    code
    count = 0
    
    def increase(count):
        return count + 1         # compute on the input, return the result
    
    count = increase(count)      # caller updates the global
    print(count)                 # 1

    Pass data in, return data out. No global mutation, no surprises, testable. This is the right way 95% of the time.

    The fix #2: global keyword (when you truly must)

    code
    count = 0
    
    def increase():
        global count             # "I mean the GLOBAL count"
        count += 1
    
    increase()
    increase()
    print(count)                 # 2 — actually changed

    global tells Python "assignments here target the file-level variable." It works — and real programs do use it for genuinely global state (a config flag, a "logged in" marker). But every global is a hidden thread connecting distant code; use it sparingly.

    LEGB — the lookup order

    When Python meets a name, it searches four levels in order:

  • L — Local: inside the current function
  • E — Enclosing: inside an outer function (if functions nest)
  • G — Global: at the file's top level
  • B — Built-in: Python's own names (print, len, True)
  • First match wins. Which explains this classic:

    code
    print = "hello"      # you just shadowed the BUILT-IN print!
    print(print)         # "hello" — and print() is now broken

    Shadowing built-ins (list = [1,2], sum = 0, print = ...) is legal but sabotages yourself. Avoid naming things list, sum, max, str, input, type.

    Locals die with the function

    code
    def make_name():
        local_name = "temporary"
    
    make_name()
    print(local_name)      # NameError — local_name no longer exists

    Locals are born on call and die at return. Anything you need after the function must be returned.

    Common Errors & Fixes

  • `UnboundLocalError` — you assigned to a global's name inside a function. Restructure with return, or declare global.
  • "My function didn't change my variable" — assignment created a local. Return the new value and reassign outside.
  • `NameError` on a variable from another function — locals don't leak between functions. Pass it as a parameter.

  • ✅ Checkpoint

  • Can a function *read* a global? *(Yes)*
  • Can it *change* a global without global? *(No — assignment creates a local)*
  • What does LEGB stand for? *(Local, Enclosing, Global, Built-in)*
  • What's the professional alternative to global? *(Pass in, return out)*
  • Next: lambda, map, and filter — one-line functions for one-line jobs.