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
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:
def level_up():
level = 2
print("New level:", level)
level_up()
print("Done")New level: 2 Done
level was born inside level_up and vanished when it returned. That's scope: where a variable lives.
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:
player = "Nova"
def greet():
print("Welcome,", player)
greet()
print("Still here:", player)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.
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:
score = 0
def add_points():
score = 100 # a NEW local variable
print("inside:", score)
add_points()
print("outside:", 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().
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.