Python Basics — Local & Global Scope

2 minute read

Local & Global Scope

Every variable in Python lives in a scope — the region of code where it can be accessed. Understanding the difference between local and global scope prevents some of the most common bugs beginners encounter.

Local Variables

Variables created inside a function are local — they only exist while the function is running:

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

greet()        # Hello!
# print(message)  # NameError: name 'message' is not defined

Each function call gets its own fresh set of local variables:

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

print(counter())  # 1
print(counter())  # 1  — not 2, because count resets every call

Global Variables

Variables created outside any function, at the module level, are global:

language = "Python"   # global variable

def show_language():
    print(language)   # can READ global variables

show_language()  # Python
print(language)  # Python — still accessible here too

Accessing Global from Local Scope

Functions can read global variables but cannot assign to them without the global keyword:

name = "Alice"

def greet():
    # Reading the global variable — works fine
    print(f"Hello, {name}!")

greet()  # Hello, Alice!

Variable Shadowing

If you assign to a variable with the same name as a global, Python creates a new local variable that shadows the global:

color = "blue"    # global

def paint():
    color = "red"   # local — shadows the global
    print(color)    # red

paint()
print(color)       # blue — global unchanged

The local color and global color are completely different variables.

UnboundLocalError Explained

This is one of the most confusing errors for beginners:

count = 10

def increment():
    count = count + 1   # UnboundLocalError!
    return count

# increment()  # UnboundLocalError: local variable 'count' referenced before assignment

Why? Python sees count = ... inside the function, so it treats count as local. But on the right side of =, it tries to read count before it’s been assigned — hence the error.

Fixes

# Fix 1: Pass as argument (preferred)
count = 10

def increment(c):
    return c + 1

count = increment(count)
print(count)  # 11

# Fix 2: Use the global keyword (use sparingly)
count = 10

def increment():
    global count
    count = count + 1

increment()
print(count)  # 11

Local vs Global — Side by Side

x = "global"

def outer():
    x = "outer local"

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

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

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

# Output:
# inner: inner local
# outer: outer local
# global: global

Each level has its own independent x.

Function Parameters Are Local

def double(n):
    n = n * 2    # n is local
    return n

value = 5
result = double(value)
print(result)  # 10
print(value)   # 5 — unchanged

Parameters behave like local variables — assigning to them doesn’t affect the caller.

Watch out with mutable objects: While reassigning a parameter doesn’t affect the caller, mutating a mutable object (like a list) does:

def add_item(lst):
    lst.append("new")   # mutates the original list

my_list = [1, 2, 3]
add_item(my_list)
print(my_list)  # [1, 2, 3, 'new'] — original changed!

Summary

Concept Description
Local variable Created inside a function; exists only during that call
Global variable Created at module level; accessible everywhere in the module
Shadowing Local variable with the same name as a global — hides the global
UnboundLocalError Trying to read a local variable before it’s assigned
Parameters Always local to the function

Next up: LEGB Rule →

Updated: