Learn Without Walls
← Previous Lesson Lesson 4 of 4 Practice Problems →

Lesson 9.4: Scope – Local vs Global

What You'll Learn

1. What is Scope?

Scope determines where in your program a variable can be accessed. A variable defined inside a function cannot be seen outside that function, and vice versa (with some rules).

Scope: The region of a program where a variable is recognized and accessible. Python has two main scopes: local (inside a function) and global (outside all functions).

2. Local Variables

A variable created inside a function is local to that function. It only exists while the function is running and cannot be accessed from outside:

def my_function():
    message = "I am local!"   # local variable
    print(message)

my_function()

# This will cause a NameError:
# print(message)  # 'message' does not exist out here
I am local!

Function parameters are also local variables:

def double(x):
    result = x * 2   # both 'x' and 'result' are local
    return result

print(double(5))
# print(x)       # NameError: x is not defined
# print(result)  # NameError: result is not defined
10

Each Call Gets Its Own Local Variables

def counter():
    count = 0
    count += 1
    print(f"count = {count}")

counter()
counter()
counter()
count = 1 count = 1 count = 1

Each call creates a brand-new count variable that starts at 0. The variable from the previous call is gone.

3. Global Variables

A variable created outside all functions is global. Functions can read global variables, but they cannot change them without special syntax:

greeting = "Hello"   # global variable

def say_hello(name):
    # We can READ the global variable
    print(f"{greeting}, {name}!")

say_hello("Alice")
print(greeting)  # still accessible out here
Hello, Alice! Hello

Local Shadows Global

If you assign to a variable inside a function, Python creates a new local variable that shadows (hides) any global variable with the same name:

color = "blue"   # global

def paint():
    color = "red"   # NEW local variable, does NOT change global
    print(f"Inside: {color}")

paint()
print(f"Outside: {color}")
Inside: red Outside: blue

4. The global Keyword

If you truly need to modify a global variable inside a function, use the global keyword:

score = 0

def add_points(points):
    global score  # tells Python to use the global variable
    score += points
    print(f"Score is now: {score}")

add_points(10)
add_points(5)
print(f"Final score: {score}")
Score is now: 10 Score is now: 15 Final score: 15
Best Practice: Avoid using global whenever possible. It makes code harder to understand and debug because any function could change the variable. Instead, pass values as arguments and return results.

Better Alternative: Use Parameters and Return

# Instead of using global:
def add_points(current_score, points):
    """Add points and return the new score."""
    return current_score + points

score = 0
score = add_points(score, 10)
score = add_points(score, 5)
print(f"Final score: {score}")
Final score: 15

This approach is clearer: you can see exactly where score changes.

5. The LEGB Rule

When Python encounters a variable name, it searches for it in this order:

LEGB Rule:
  1. Local — inside the current function
  2. Enclosing — inside any enclosing (outer) function
  3. Global — at the module (file) level
  4. Built-in — Python's built-in names (print, len, etc.)
Python stops searching as soon as it finds the name.
x = "global"

def outer():
    x = "enclosing"

    def inner():
        x = "local"
        print(f"inner: {x}")

    inner()
    print(f"outer: {x}")

outer()
print(f"global: {x}")
inner: local outer: enclosing global: global

6. Best Practices

Scope Best Practices

  • Prefer local variables: Keep data inside functions whenever possible
  • Pass data through parameters: Functions should get their input from arguments, not global variables
  • Return results: Use return to send data back rather than modifying globals
  • Use global sparingly: Only when absolutely necessary (like configuration constants)
  • Use ALL_CAPS for constants: If you define a global that should not change, name it in uppercase: MAX_SIZE = 100
  • Avoid shadowing: Do not give local variables the same name as global ones or built-in functions
# BAD: Shadowing built-in 'list'
# list = [1, 2, 3]  # Now you can't use list() anymore!

# GOOD: Use a descriptive name
numbers = [1, 2, 3]

# BAD: Relying on global state
# total = 0
# def add(x):
#     global total
#     total += x

# GOOD: Pure function
def add(total, x):
    return total + x

Check Your Understanding

Question: What does this code print?

x = 10

def change_x():
    x = 20

change_x()
print(x)

Answer: 10

The function creates a local variable x set to 20. This does not affect the global x. Without the global keyword, the assignment inside the function creates a new local variable.

Try It Yourself

  1. Create a global variable name = "World". Write a function that prints it without modifying it.
  2. Write a function that tries to change the global name without using global. Print name after calling it to verify it did not change.
  3. Rewrite the function using global and verify the change works.
  4. Finally, refactor to avoid global entirely by using parameters and return values.

Key Takeaways

← Previous: Default & Keyword Args Practice Problems →