Skip to content
Foxipa

Suggest an edit

Tell us what should be corrected, clarified, or improved. Submission will be connected to Foxipa’s contribution service later.

No information is sent anywhere yet. Your suggestion is only prepared in your browser.

Learning

Python Names, Scopes, and Namespaces

Understand how Python binds names, organizes namespaces, resolves names through nested scopes, and uses global and nonlocal when rebinding is intentional.

Levels: Beginner ~25 min read

Basic

A name is a label that refers to an object. A namespace is a place where those name-to-object bindings are kept. A scope is the part of a program where a namespace can be accessed directly by an unqualified name.

Names and namespaces

Python does not make a name itself contain a value. Instead, a name is bound to an object. Different namespaces can contain the same name without interfering with one another.

python
score = 10

def show_score():
    score = 20
    print(score)

show_score()
print(score)

The function call has a local name named score; the module-level score remains 10.

The module-level name and the function-local name are different bindings even though both are spelled score.

Local and global scopes

A function call creates a local namespace for that invocation. Names bound inside the function are normally local. Names defined at module level belong to the module global namespace.

python
message = "module"

def read_message():
    print(message)

read_message()

A function can read a name from an enclosing scope when it has not created a local binding with that name.

A name used inside a function is not automatically local just because the function uses it. What matters is whether the function block binds that name.

How Python resolves a name

For an ordinary function, Python searches the current local scope first, then enclosing function scopes, then the module global scope, and finally the built-in namespace.

python
language = "Python"

def outer():
    topic = "scopes"

    def inner():
        print(topic)
        print(language)
        print(len("ok"))

    inner()

outer()

The inner function finds topic in the enclosing function, language in the module, and len in the built-in namespace.

If no binding can be found, Python raises NameError.

An assignment can make a name local

If a function contains a binding operation for a name, that name is treated as local to that function unless the function explicitly declares it global or nonlocal.

python
count = 10

def read_before_local_assignment():
    print(count)
    count = count + 1

def read_missing_name():
    print(missing_name)

for function in (read_before_local_assignment, read_missing_name):
    try:
        function()
    except NameError as error:
        print(type(error).__name__)

The function that assigns to count treats it as local throughout the function, so its earlier read raises UnboundLocalError. The second function has no binding for missing_name in its available namespaces, so it raises NameError.

A binding operation anywhere in a function block makes that name local throughout the block unless global or nonlocal changes the rule. Python does not fall back to a module-level name when the local binding has not received a value. The resulting UnboundLocalError is a subclass of NameError; a plain NameError means name resolution found no binding for the requested name in the namespaces that apply.

This rule is why a seemingly harmless assignment can change how Python interprets another use of the same name inside the function.

Rebinding a module-level name with global

Use global when a function needs to rebind a name in its module global namespace. It is usually clearer to pass values in and return new values when that design works.

python
count = 0

def increase():
    global count
    count += 1

increase()
increase()
print(count)

global tells the function that assignments to count should update the module-level binding.

Rebinding an enclosing function name with nonlocal

Use nonlocal when a nested function needs to rebind a name that already exists in the nearest enclosing function scope.

python
def make_counter():
    count = 0

    def next_count():
        nonlocal count
        count += 1
        return count

    return next_count

counter = make_counter()
print(counter())
print(counter())

nonlocal lets next_count() update the count binding belonging to make_counter().

The name must already exist in an enclosing function scope; otherwise nonlocal causes a SyntaxError.

Prefer the smallest useful scope

Local names are often easier to reason about because their lifetime and effect are limited. Prefer parameters and return values for ordinary data flow; use global or nonlocal deliberately when shared state is genuinely part of the design.

Key idea: names, namespaces, and scopes explain why the same spelling can refer to different objects in different parts of a program.

Was this page helpful?

Mark this learning resource complete to track your learning progress.