Scope is where in your code a variable can be seen and used — the same idea from Intro to Programming, with one meaningful wrinkle specific to Python.
A variable created inside a function only exists inside that function:
def set_name():
name = "Priya" # local to set_name()
print(name) # works fine here
set_name()
# print(name) # NameError — name doesn't exist out hereA Python function can read a global variable without any special keyword — no import or declaration needed. The global keyword is only required if you want to reassign one, not just read it:
site_name = "Learn Computer Academy"
def show_name():
print(site_name) # works — reading a global needs nothing special
show_name()Assigning to a name inside a function makes Python treat it as local by default — even if a global with the same name exists. global is required to override that and reassign the actual global variable:
count = 0
def increment_broken():
count = count + 1 # UnboundLocalError — count is treated as local here,
# and it hasn't been assigned yet at this point
def increment():
global count
count = count + 1 # now this correctly modifies the global
increment()
print(count) # 1Prefer parameters over global
Relying on global throughout a codebase makes it hard to trace where a value actually comes from. The cleaner, more common pattern is passing the value in as a parameter and returning the new value, rather than mutating a global directly.
One more real difference from some languages: a variable created inside an if or for block in Python is not limited to that block — it's visible for the rest of the enclosing function:
def check(n):
if n > 0:
result = "positive"
print(result) # this works even outside the if block, as long as n > 0 ran
check(5) # "positive"A function defined inside another function can read its enclosing function's variables automatically — same rule as reading a global. To reassign one, nonlocal is the equivalent of global one level up, rather than jumping all the way to global scope:
def make_counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
counter = make_counter()
print(counter()) # 1
print(counter()) # 2 — count is remembered between callsThis pattern — a function returning another function that remembers state — is called a closure. It's a genuinely useful trick, but a niche one; don't worry if it takes a re-read to click.