Python Scope

Scope determines where in your program a variable can be seen and used, and Python decides this by where the variable is created.

Local and global scope

A variable created inside a function belongs to that function's local scope and exists only while the function runs. A variable created at the top level of a file lives in the global scope and can be read from anywhere, including inside functions. Keeping variables local by default helps prevent one part of a program from accidentally changing another.

A local variable stays inside its function

def show():
    message = "inside"   # local variable
    print(message)

show()          # inside
print(message)  # NameError: name 'message' is not defined

Reading globals from inside a function

A function can read a global variable without any special syntax. Trouble only arises when you try to assign to that name: by default, assigning inside a function creates a new local variable instead of changing the global one.

Reading works, but assigning creates a local

count = 10

def read_it():
    print(count)   # reads the global: 10

def shadow_it():
    count = 99     # this is a new local, not the global
    print(count)   # 99

read_it()
shadow_it()
print(count)       # still 10

The global keyword

When you genuinely need a function to change a global variable, declare it with the global keyword before assigning to it. This tells Python to use the existing global name instead of creating a local one. Use this sparingly, since functions that modify globals can be harder to follow.

Modifying a global on purpose

total = 0

def add(amount):
    global total
    total += amount

add(5)
add(3)
print(total)  # 8

Nested functions and nonlocal

When one function is defined inside another, the inner function can read variables from the enclosing function. To reassign such an enclosing variable, use the nonlocal keyword, which is the counterpart to global for a surrounding function rather than the module level.

Reaching an enclosing variable with nonlocal

def counter():
    n = 0
    def step():
        nonlocal n
        n += 1
        return n
    return step

next_value = counter()
print(next_value())  # 1
print(next_value())  # 2
Note: Python looks up names using the LEGB rule: Local, then Enclosing, then Global, then Built-in. The first match found is the one used.
ScopeWhere the variable livesKeyword to reassign it elsewhere
LocalInside the current functionNone needed
EnclosingIn a surrounding functionnonlocal
GlobalAt the top level of the moduleglobal
Built-inProvided by Python itselfNot applicable