What Is an Enclosing Function?
When a function is defined inside another function, the outer function is called the enclosing function and the function defined inside it is called the nested function.
def outer(): # Enclosing function
def inner(): # Nested function
print("Hello")
inner()
outer()
Explanation:
outer()is the enclosing function because it containsinner().inner()is the nested function because it is defined insideouter().
What Is the nonlocal Keyword in Python?
The nonlocal keyword is used inside a nested function when it needs to modify a variable belonging to an enclosing function.
A nested function can read a variable from its enclosing function without using nonlocal. The keyword is needed when the nested function needs to assign a new value to that enclosing variable.
Syntax of the nonlocal Keyword
Use the nonlocal keyword followed by the name of the variable from the enclosing function that the nested function needs to modify.
def outer():
variable = value
def inner():
nonlocal variable
variable = new_value
Explanation: The nonlocal keyword tells Python that variable refers to the variable in the enclosing function rather than creating a new local variable inside the nested function.
Reading a Variable From an Enclosing Function
def outer():
message = "Hello"
def inner():
print(message)
inner()
outer()
# Output:
Hello
Explanation:
messageis created inside theouter()function.inner()does not have its ownmessagevariable, so it accesses themessagevariable fromouter().- Here, the goal is to read
message, so thenonlocalkeyword is not needed.
Modifying a Variable From an Enclosing Function
def counter():
count = 0
def increase():
nonlocal count
count += 1
print(count)
increase()
increase()
counter()
# Output:
1
2
Explanation:
countis created inside thecounter()function.nonlocal countallowsincrease()to modify thecountvariable fromcounter().- Each call to
increase()changes the value ofcount.
Note: Without nonlocal, Python treats count as a local variable inside increase(). Since the local count has no value before count += 1, Python raises an UnboundLocalError.
Uses of the nonlocal Keyword in Python
The nonlocal keyword is used when a nested function needs to modify a variable from an enclosing function.
- Modifying a variable in an enclosing function
- Keeping a value between calls to a nested function
Practical Examples of the nonlocal Keyword in Python
Here are some practical examples that show how the nonlocal keyword works in real situations:
Example 1: Function Counter With nonlocal
def create_counter():
count = 0
def increase():
nonlocal count
count += 1
return count
return increase
counter = create_counter()
print(counter())
print(counter())
print(counter())
# Output:
1
2
3
Explanation: Here, count belongs to create_counter(). The nested increase() function uses nonlocal to update it each time the counter is called.
Example 2: Updating a User Preference
def create_user():
theme = "Light"
def change_theme():
nonlocal theme
theme = "Dark"
change_theme()
print(theme)
create_user()
# Output:
Dark
Explanation: The theme variable belongs to create_user(). The nested change_theme() function uses nonlocal to change its value.
Example 3: Tracking a Running Total
def create_total():
total = 0
def add_amount(amount):
nonlocal total
total += amount
return total
return add_amount
add_to_total = create_total()
print(add_to_total(100))
print(add_to_total(50))
print(add_to_total(25))
# Output:
100
150
175
Explanation: The total variable belongs to create_total(). The nested add_amount() function uses nonlocal to keep updating the same total across multiple calls.
Common Mistakes With the nonlocal Keyword
Using nonlocal Without an Enclosing Variable
def outer():
def inner():
nonlocal count
count = 1
inner()
outer()
# Error:
SyntaxErrorExplanation: The nonlocal keyword requires a variable with the same name in an enclosing function scope. No such variable exists here, so Python raises a SyntaxError.
Using an Enclosing Variable Without nonlocal
def counter():
count = 0
def increase():
count += 1
increase()
counter()
# Error:
UnboundLocalErrorExplanation: Because count is assigned inside increase(), Python treats it as a local variable. The function therefore needs nonlocal to modify the enclosing count.
Related Topics
The nonlocal keyword is part of Python’s wider variable-scope system. The comparison between nonlocal and global is covered separately.
Key Takeaways: nonlocal keyword
Here are some key points to remember about the nonlocal keyword in Python.
- The
nonlocalkeyword works with variables in an enclosing function. - A nested function can read an enclosing variable without
nonlocal. nonlocalis needed when a nested function modifies an enclosing variable.- The variable must exist in an enclosing function scope.
nonlocalandglobalrefer to different scopes.