Python - Scope

Overview

Estimated time: 20–30 minutes

Understand how Python resolves names using the LEGB rule and how to use global and nonlocal sparingly.

Learning Objectives

  • Explain the LEGB rule (Local, Enclosing, Global, Built-in).
  • Use nonlocal for closures and global when necessary.
  • Avoid namespace collisions and prefer explicit arguments.

Prerequisites

LEGB and closures

def outer():
    x = 10
    def inner():
        return x  # from enclosing scope
    return inner

fn = outer()
print(fn())  # 10

Using nonlocal

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

c = counter()
print(c(), c(), c())

Using global

total = 0

def add(n: int) -> None:
    global total
    total += n

add(5)
print(total)

Common Pitfalls

  • Overusing global: prefer passing values and returning results.
  • Shadowing built-ins: avoid names like list, dict, str.

Checks for Understanding

  1. What does LEGB stand for?
  2. When is nonlocal appropriate?
Show answers
  1. Local, Enclosing, Global, Built-in.
  2. To mutate a variable in an enclosing (but not global) scope from an inner function.

Exercises

  1. Write a closure-based accumulator using nonlocal.
  2. Refactor a function that uses global to accept parameters and return values.