Learning LibraryCore Coding LibraryTeens

Scope in Python: where a variable lives

Set score inside a function and the outer score doesn't budge. That's scope — the rule for where a variable exists and who can see it.

The big idea

A variable assigned inside a function is local to that function; it can't be seen outside, and assigning it doesn't touch a global of the same name.

See it in code

1The basics

A variable created inside a function is local — it exists only while the function runs. level lives inside level_up and does its job there:

python
def level_up():
    level = 2
    print("New level:", level)

level_up()
print("Done")
Run it — the local variable works inside the function:
New level: 2
Done

level was born inside level_up and vanished when it returned. That's scope: where a variable lives.

2A step further

A function can read a variable from outside — as long as it only reads it. Here greet reaches out to the global player with no trouble:

python
player = "Nova"

def greet():
    print("Welcome,", player)

greet()
print("Still here:", player)
Run it — reading the outer variable is allowed:
Welcome, Nova
Still here: Nova

Reading an outer variable inside a function is fine. The catch comes when you try to assign one — that's next.

3In our world

Now the twist that reading didn't have. When add_points assigns score = 100, it creates a new, local variable — it shadows the outer one but doesn't change it. After the call, the global score is still 0:

python
score = 0

def add_points():
    score = 100          # a NEW local variable
    print("inside:", score)

add_points()
print("outside:", score)
Run it — the inner assignment doesn't reach the outer score:
inside: 100
outside: 0

inside saw 100; outside is still 0. The local score vanished when the function returned. The clean fix isn't global — it's to return the value and let the caller assign it: score = add_points().

The same idea, everywhere

Scope keeps large programs from turning into chaos: each function has its own private variables, so names in one can't clobber names in another. Python resolves a name by looking Local, then Enclosing, then Global, then Built-in (the 'LEGB' rule). Understanding it explains a whole class of 'why didn't my value change?' bugs.

Try it yourself

Add return score to the function and write score = add_points(), then confirm the outer value updates. Next, read (don't assign) the global inside the function — print(score) works, because reading an outer variable is allowed.

The common mistake

Reaching for the global keyword to 'fix' this. It works, but globals make code hard to follow and test. Prefer passing values in as arguments and handing results back with return — functions that don't secretly mutate outside state are far easier to reason about.

What it unlocks

Scope refines how you use functions, arguments, and return values to move data cleanly.