Nearby lessons

120 of 159

Python - Nonlocal Keyword

📌 What You Will Learn
  • Understand the nonlocal keyword
  • Modify an enclosing function's variable from a nested function
  • See what happens when nonlocal is not used
  • Know when nonlocal cannot be used
  • Compare global and nonlocal

What is the nonlocal Keyword?

The nonlocal keyword is used inside a nested function to modify a variable that belongs to its enclosing function.

In other words, nonlocal lets an inner function change a variable of the outer function in which it is defined.

Nested Functions and the Enclosing Scope

Consider a function outer() that defines a variable x and then defines another function inner() inside itself.

🐍Code Cell
1def outer():
2 x = 100
3 
4 def inner():
5 x = 200
6 print("Inner x:", x)
7 
8 inner()
9 
10 print("Outer x:", x)
11 
12 
13outer()
Output
Inner x: 200
Outer x: 100

Explanation

Inside inner(), the statement x = 200 creates a local variable of inner(). It does not touch the x of outer().

So inner() prints 200, but outer() still sees 100.

The Problem

Now suppose we want the inner function to change the outer function's variable so that the outer function also sees the new value.

Plain assignment will not work because it creates a local variable. This is exactly the problem that nonlocal solves.

Using nonlocal

Inside the nested function, declare nonlocal x before assigning it:

🐍Code Cell
1def outer():
2 x = 100
3 
4 def inner():
5 nonlocal x
6 x = 200
7 print("Inner x:", x)
8 
9 inner()
10 
11 print("Outer x:", x)
12 
13 
14outer()
Output
Inner x: 200
Outer x: 200

Explanation

The nonlocal x statement tells Python that x refers to the enclosing function's variable, not a local variable of inner().

Now x = 200 actually modifies the x of outer(), so both inner() and outer() print 200.

Comparison: Without vs With nonlocal

Without nonlocal With nonlocal
Creates a local variable in the inner function. Refers to the enclosing function's variable.
The outer variable is unchanged. The outer variable is modified.
The outer function still sees the old value. The outer function sees the new value.

Example: Counter with nonlocal

A common use of nonlocal is a counter that the inner function increments:

🐍Code Cell
1def counter():
2 count = 0
3 
4 def increment():
5 nonlocal count
6 count += 1
7 print("Count:", count)
8 
9 increment()
10 increment()
11 increment()
12 
13 
14counter()
Output
Count: 1
Count: 2
Count: 3

Explanation

Without nonlocal, count += 1 inside increment() would create a local variable and raise an error on first use, because a local count does not exist yet.

With nonlocal count, each call to increment() modifies the same count of counter(), so the count keeps increasing.

Rules of the nonlocal Keyword

  • nonlocal can only be used inside a nested function.
  • The variable must already exist in an enclosing function.
  • nonlocal cannot be used for variables at module level; use global instead.
  • The name must appear in nonlocal before it is assigned in the nested function.

global vs nonlocal

global nonlocal
Refers to module-level variables. Refers to enclosing function variables.
Can be used in any function. Can only be used in a nested function.
The variable may not exist yet. The variable must already exist in the enclosing scope.
Works without nesting. Requires an enclosing function.

When nonlocal Fails

If no variable with the given name exists in an enclosing function, Python raises a SyntaxError.

🐍Code Cell
1def outer():
2 def inner():
3 nonlocal x
4 x = 10
5 
6 
7outer()
Output
SyntaxError: no binding for nonlocal 'x' found

Explanation

Here, x does not exist in the enclosing scope, so nonlocal x is invalid. A nonlocal name must always refer to a variable that already exists in an enclosing function.

📝 Key Takeaways
  • nonlocal allows a nested function to modify a variable from its enclosing function
  • Without nonlocal, an assignment inside a nested function creates a local variable
  • nonlocal only works inside a nested function and its enclosing function
  • nonlocal cannot be used for module-level variables; use global for those
  • There must already be a binding of the variable in the enclosing scope for nonlocal to work

🧠 Test Your Knowledge

10 Questions
Progress: 0 / 10