Definitions - Nonlocal Variables in Python 2026
A nonlocal variable is a variable that belongs to the enclosing (outer) function’s scope and is accessed or modified from within a nested (inner) function. The nonlocal keyword is used to explicitly tell Python that we want to refer to the variable in the nearest enclosing scope rather than creating a new local variable.
TL;DR — Key Definitions 2026
- Nonlocal Variable: A variable defined in an enclosing function that can be read or modified by a nested function
- nonlocal Keyword: Declares that a name refers to a variable in the nearest enclosing scope (not global, not local)
- Enclosing Scope: The scope of the function that contains the nested function
- Closure: A nested function that "remembers" its nonlocal variables even after the outer function has returned
1. Clear Definition with Example
def outer():
x = 10 # This is a nonlocal variable for the inner function
def inner():
nonlocal x # Explicitly refer to the variable in outer scope
x += 5 # Modifies the nonlocal variable
print("Inside inner:", x)
inner()
print("Inside outer after inner:", x)
outer()
# Output:
# Inside inner: 15
# Inside outer after inner: 15
2. Without nonlocal (Common Mistake)
def outer():
x = 10
def inner():
x = 20 # This creates a NEW local variable!
print("Inside inner:", x)
inner()
print("Inside outer:", x) # Still 10 - unchanged
outer()
3. Best Practices for Nonlocal Variables (2026)
- Always use the
nonlocalkeyword when you intend to modify a variable from the enclosing scope - Keep the number of nonlocal variables small for readability
- Document the purpose of each nonlocal variable clearly
- When state becomes complex, prefer a class over many nonlocal variables
- Use type hints on both outer and inner functions
Local, Enclosing, Global and Built-In Names
Python looks up a name in four scopes, in this order: Local, Enclosing, Global and Built-in, often remembered as LEGB. A nonlocal variable is a name in the enclosing scope, that is, a local variable of an outer function that an inner function uses.
Reading an enclosing variable needs no declaration. Rebinding it requires the nonlocal statement; otherwise the assignment creates a new local name in the inner function.
The built-in scope holds names like len and print. Defining your own variable called len hides the built-in in that scope, which is a common source of confusing errors.
Seeing which scope a name comes from makes closures, decorators and many error messages much easier to understand.
Worked Example: One Name in Four Scopes
We define the same name in several scopes and print which value each function sees.
x = "global"
def outer():
x = "enclosing"
def inner_read():
return x # E: found in outer
def inner_local():
x = "local" # L: new local name
return x
def inner_rebind():
nonlocal x
x = "rebound enclosing"
print(inner_read(), "|", inner_local())
inner_rebind()
print("outer now sees:", x)
outer()
print("module still sees:", x)
print(len("abc"), "uses the built-in len")
inner_read finds the enclosing value and inner_local creates its own local. After inner_rebind uses nonlocal, outer sees rebound enclosing. The module x is unchanged, and len still comes from the built-in scope.
Practical Tips
Use a linter such as pylint or ruff to catch names that shadow built-ins. These tools flag variables called list or id before they cause confusing errors.
When a name behaves unexpectedly, print locals() inside the function to see which names are local at that point.
Common Mistakes
- Shadowing built-ins such as list, len or id.
- Expecting an inner assignment to change the outer variable.
- Confusing nonlocal with global.
- Reusing one name for different meanings in nested scopes.
Quick Summary
- Lookup order is Local, Enclosing, Global, Built-in.
- Nonlocal variables live in an enclosing function.
- Rebinding them needs nonlocal.
- Avoid shadowing built-in names.
Conclusion
Understanding nonlocal variables is essential for working effectively with nested functions and closures in Python. The nonlocal keyword clearly signals your intention to modify a variable from the enclosing scope rather than creating a local one. In 2026, proper use of nonlocal variables leads to cleaner, more predictable, and maintainable code.
Next steps:
- Review your nested functions and ensure every reassignment of enclosing variables uses the
nonlocalkeyword