Python course menu
Python Variable Scope: Local, Global, nonlocal and the LEGB Rule
Understand variable scope in Python: local and global variables, the LEGB lookup rule, why UnboundLocalError happens, the global and nonlocal keywords, closures, and why returning values beats globals.
On this page
Scope is the region of a program where a variable name can be seen and used. Variables created inside a function live only inside that function. Understanding scope explains some confusing errors and helps you write functions that do not interfere with each other.
Local variables#
A variable assigned inside a function is local: it exists only while the function runs.
def make_total():
total = 10
return total
print(make_total())
print(total)10
NameError: name 'total' is not definedOutside the function, total does not exist. This is a feature: two functions can both use a variable called total without clashing.
Global variables#
A variable assigned at the top level of a file is global. Functions can read it:
rate = 0.18
def with_tax(price):
return price * (1 + rate)
print(with_tax(100))118.0Same name, different variables#
Assigning inside a function creates a new local variable, even if a global has the same name:
name = "Asha"
def greet():
name = "Ravi"
print("inside:", name)
greet()
print("outside:", name)inside: Ravi
outside: AshaThe global name was never touched.
The LEGB rule#
When Python looks up a name, it searches four scopes in order and uses the first match:
x = "global"
def outer():
x = "enclosing"
def inner():
x = "local"
print("inner:", x)
inner()
print("outer:", x)
outer()
print("module:", x)inner: local
outer: enclosing
module: globalUnboundLocalError#
This surprises almost everyone the first time:
count = 0
def increment():
count = count + 1
increment()UnboundLocalError: cannot access local variable 'count' where it is not associated with a valueBecause count is assigned inside the function, Python treats it as local for the whole function. So count + 1 tries to read the local count before it has a value.
The global keyword#
global tells Python that a name inside the function refers to the global variable:
count = 0
def increment():
global count
count += 1
increment()
increment()
print(count)2It works, but global state makes programs harder to understand: any function could change count at any time. The cleaner design passes values in and returns results:
count = 0
def increment(n):
return n + 1
count = increment(count)
count = increment(count)
print(count)2nonlocal and closures#
In nested functions, nonlocal lets the inner function change a variable of the enclosing function:
def counter():
count = 0
def increment():
nonlocal count
count += 1
return count
return increment
tick = counter()
print(tick(), tick(), tick())1 2 3increment "remembers" count even after counter() has finished. A function that carries variables from its enclosing scope like this is called a closure. Closures are the foundation of decorators.
Blocks do not create scope#
Unlike many languages, if blocks and for loops do not create their own scope in Python:
for i in range(3):
pass
print(i)
if True:
msg = "created inside if"
print(msg)2
created inside ifOnly functions (and classes, modules and comprehensions) create new scopes.
Common mistakes#
Practice#
Practice exercise
Predict the output, then check your answer:
x = 5
def change():
x = 10
return x
y = change()
print(x, y)Show hint
The x = 10 inside the function creates a local variable.
Show solution
5 10The function's x is local, so the global x stays 5. The function returns its local value, 10, which is stored in y.
Key takeaway#
Finished this lesson?