Scope and Closures

Loading concept...

🏠 The House of Variables: Understanding Scope and Closures

Imagine your code is a big house with many rooms. Each room has its own secrets, and some secrets can only be found in certain rooms. Let’s explore this magical house together!


🌟 What is Scope?

Scope is like asking: “Where can I find this toy?”

Think of it this way:

  • Your bedroom has YOUR toys
  • The living room has FAMILY toys everyone can use
  • Your toy box inside your room? Only YOU know what’s in there!

In Python, scope means: Where a variable lives and who can see it.


🔤 The LEGB Rule: Four Rooms in Our House

Python looks for variables in 4 places, always in this order:

L → E → G → B

The Four Rooms:

Letter Room Name What It Means
L Local Inside the current function
E Enclosing Inside outer functions
G Global At the top level of your file
B Built-in Python’s own special tools

🏠 Room 1: LOCAL Scope (Your Bedroom)

Variables created inside a function stay inside that function.

def my_room():
    toy = "teddy bear"  # LOCAL
    print(toy)  # Works!

my_room()
print(toy)  # ERROR! Can't see it!

Think of it: Your teddy bear is in YOUR room. Mom can’t see it from the kitchen!


🏠 Room 2: ENCLOSING Scope (The Big Room Around You)

When a function is inside another function, the inner one can see the outer one’s stuff.

def living_room():
    snack = "cookies"  # ENCLOSING

    def my_corner():
        print(snack)  # Can see it!

    my_corner()

living_room()  # Prints: cookies

Think of it: You’re playing in a corner of the living room. You can see the cookies on the coffee table!


🌍 Room 3: GLOBAL Scope (The Whole House)

Variables at the top of your file (not inside any function) are global.

family_pet = "dog"  # GLOBAL

def any_room():
    print(family_pet)  # Everyone sees it!

any_room()  # Prints: dog

Think of it: The family dog walks everywhere in the house. Everyone knows him!


🔧 Room 4: BUILT-IN Scope (Python’s Magic Toolbox)

Python has special words like print, len, sum that work everywhere.

numbers = [1, 2, 3]
print(len(numbers))  # 3
# len is BUILT-IN

Think of it: Like electricity in your house—it’s always there, everywhere!


🔍 How Python Searches (LEGB in Action)

graph TD A[Looking for variable X] --> B{Is X in LOCAL?} B -->|Yes| C[Use it!] B -->|No| D{Is X in ENCLOSING?} D -->|Yes| C D -->|No| E{Is X in GLOBAL?} E -->|Yes| C E -->|No| F{Is X in BUILT-IN?} F -->|Yes| C F -->|No| G[ERROR! Not found]

🌐 The global Keyword: Talking to the Whole House

Problem: What if you want to change a house-wide rule from your room?

score = 0  # GLOBAL

def play_game():
    global score  # "I want the HOUSE score!"
    score = score + 10

play_game()
print(score)  # 10 (it changed!)

Without global:

score = 0

def play_game():
    score = score + 10  # ERROR!
    # Python thinks you want a LOCAL score
    # But you're trying to read it first!

play_game()

The Rule: Use global when you need to change a variable that lives outside your function.

⚠️ Important Warning:

  • You CAN read global variables without global
  • You NEED global to change them

🔗 The nonlocal Keyword: Talking to the Room Around You

Problem: What about changing something in the room AROUND your function?

def outer_room():
    treats = 5  # ENCLOSING

    def inner_room():
        nonlocal treats  # "The outer room's treats!"
        treats = treats - 1

    inner_room()
    print(treats)  # 4

outer_room()

When to Use Which?

Keyword Use When…
global Changing a variable at the top of your file
nonlocal Changing a variable in an outer function

🎁 Closures: Functions That Remember

A closure is like a lunchbox. When you make it in the morning, you put your sandwich inside. Later at school, you open it and your sandwich is still there!

What Makes a Closure?

  1. A function inside another function
  2. The inner function uses something from the outer function
  3. The outer function returns the inner function
def make_lunchbox(food):
    # food is "packed" in the lunchbox

    def open_lunchbox():
        return f"Yum! {food}!"

    return open_lunchbox

my_lunch = make_lunchbox("sandwich")
print(my_lunch())  # Yum! sandwich!

The magic: Even though make_lunchbox finished running, my_lunch still remembers “sandwich”!


🧮 Closures for Counting

def make_counter():
    count = 0  # This gets "remembered"

    def add_one():
        nonlocal count
        count = count + 1
        return count

    return add_one

counter = make_counter()
print(counter())  # 1
print(counter())  # 2
print(counter())  # 3

Each call remembers the previous count!


🏭 Closures as Function Factories

def make_multiplier(times):
    def multiply(number):
        return number * times
    return multiply

double = make_multiplier(2)
triple = make_multiplier(3)

print(double(5))  # 10
print(triple(5))  # 15

Think of it: You built two different machines—one doubles, one triples!


🎯 Quick Summary

graph LR A[Scope & Closures] --> B[LEGB Rule] A --> C[Keywords] A --> D[Closures] B --> B1[L: Local] B --> B2[E: Enclosing] B --> B3[G: Global] B --> B4[B: Built-in] C --> C1[global: change top-level vars] C --> C2[nonlocal: change outer func vars] D --> D1[Functions that remember] D --> D2[Inner function + outer data]

💡 Golden Rules to Remember

  1. Variables prefer to be LOCAL - Python creates local ones first
  2. Reading is easy - You can read outer variables anytime
  3. Changing needs permission - Use global or nonlocal
  4. Closures are memory keepers - They hold onto values forever
  5. LEGB is the search order - Local → Enclosing → Global → Built-in

🎮 Real-World Example: A Simple Game

player_name = "Hero"  # GLOBAL

def create_player():
    health = 100  # Will be enclosed

    def take_damage(amount):
        nonlocal health
        health = health - amount
        print(f"{player_name} has {health} HP")

    def heal(amount):
        nonlocal health
        health = health + amount
        print(f"{player_name} has {health} HP")

    return take_damage, heal

hurt, heal = create_player()
hurt(30)  # Hero has 70 HP
heal(20)  # Hero has 90 HP

See how everything works together?

  • player_name is GLOBAL (everyone knows it)
  • health is ENCLOSING (both functions share it)
  • amount is LOCAL (each call gets its own)

Now you know the secret of the House of Variables! You understand which room each variable lives in, how to change them, and how to create magical closures that remember things forever. 🏆

Loading story...

No Story Available

This concept doesn't have a story yet.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Interactive Content

This concept doesn't have interactive content yet.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Cheatsheet Available

This concept doesn't have a cheatsheet yet.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Quiz Available

This concept doesn't have a quiz yet.