Skip to content
Laviyx Learn

Try

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.

Beginner8 min readUpdated
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.

Python
def make_total():
    total = 10
    return total

print(make_total())
print(total)
Output
10
NameError: name 'total' is not defined

Outside 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:

Python
rate = 0.18

def with_tax(price):
    return price * (1 + rate)

print(with_tax(100))
Output
118.0

Same name, different variables#

Assigning inside a function creates a new local variable, even if a global has the same name:

Python
name = "Asha"

def greet():
    name = "Ravi"
    print("inside:", name)

greet()
print("outside:", name)
Output
inside: Ravi
outside: Asha

The 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:

LetterScopeExample
LLocalvariables inside the current function
EEnclosingvariables of an outer function, when functions are nested
GGlobalvariables at the top level of the module
BBuilt-innames Python provides, such as print and len
Python
x = "global"

def outer():
    x = "enclosing"
    def inner():
        x = "local"
        print("inner:", x)
    inner()
    print("outer:", x)

outer()
print("module:", x)
Output
inner: local
outer: enclosing
module: global

UnboundLocalError#

This surprises almost everyone the first time:

Python
count = 0

def increment():
    count = count + 1

increment()
Output
UnboundLocalError: cannot access local variable 'count' where it is not associated with a value

Because 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:

Python
count = 0

def increment():
    global count
    count += 1

increment()
increment()
print(count)
Output
2

It 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:

Python
count = 0

def increment(n):
    return n + 1

count = increment(count)
count = increment(count)
print(count)
Output
2

nonlocal and closures#

In nested functions, nonlocal lets the inner function change a variable of the enclosing function:

Python
def counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment

tick = counter()
print(tick(), tick(), tick())
Output
1 2 3

increment "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:

Python
for i in range(3):
    pass
print(i)

if True:
    msg = "created inside if"
print(msg)
Output
2
created inside if

Only functions (and classes, modules and comprehensions) create new scopes.

Common mistakes#

Practice#

Practice exercise

Predict the output, then check your answer:

Python
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
Output
5 10

The 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?