Everything you need to know about nonlocal in Python

The nonlocal keyword is used in nested functions to modify a variable defined in the parent function.
5 min read
Believemy logo

In Python, the nonlocal keyword is often misunderstood!

And for good reason: it is only useful in very specific cases, particularly in nested functions (closures).

However, when used properly, nonlocal makes your code cleaner and more explicit.

 

Nonlocal syntax and example

Let's take a concrete case: we have a function inside another function, and we want to modify a variable defined in the parent function. Without nonlocal, Python will create a new local variable instead of reusing the one from the parent function.

Good to know

nonlocal therefore allows you to reuse a variable that is non-local but not global.

Syntax

The nonlocal keyword is used within a nested function:

PYTHON
def outer():
    var = 10
    def inner():
        nonlocal var
        var += 5
        return var
    return inner()

What to remember from this example:

  • nonlocal must be declared before using the parent variable;
  • there is no new variable being created: the nonlocal keyword modifies an existing variable (we speak of enclosing scope - we'll talk about this again shortly!).

Finally, this keyword is unusable outside of a function unlike the global keyword.

 

Example

Let's take a more meaningful example with a counter:

PYTHON
def outer():
    counter = 0
    def inner():
        nonlocal counter
        counter += 1
        return counter
    return inner()

Here, counter is in the scope of outer(), but not in that of inner(). Thanks to nonlocal, we can access and modify it.

 

Comparison between nonlocal and global

Too often when we start with Python we tend to wrongly compare nonlocal and global.

After all, a variable that is not local is necessarily global? No!? 😋

Well no! These two keywords are totally different in their functioning.

Let's make a comparison in this summary table:

KeywordTargetExample

global

Variable defined in the module (at the base)

Modify a configuration, create a parameter...

nonlocal

Variable in a nested functionClosures, counters, etc

As we can see, global creates / uses a variable available throughout the entire module, when nonlocal uses a variable in a parent function.

 

Understanding the enclosing scope

In Python, each variable lives in a scope. Understanding the enclosing scope is essential to correctly use nonlocal.

Let's start from the basics!

There are 4 levels of scope in Python:

  1. Local: inside a function (or a loop);
  2. Enclosing: in an enclosing function;
  3. Global: in the current module;
  4. Built-in: which is integrated by Python.

With nonlocal we only act on the enclosing scope (so on what we call enclosing).

 

Common errors with nonlocal

Let's take a tour of the most common errors when starting with nonlocal! 😬

Error #1: Using nonlocal to define a variable in the enclosing scope

This is the most common error: we forget to declare our variable in our parent function.

PYTHON
def test():
    def inner():
        nonlocal x  # Error!
        x = 1
    inner()

A variable must already exist in the enclosing function. Otherwise, nonlocal will fail (because Python won't find our variable).

 

Error #2: Creating a conflict with a global variable

Here's a second error very present when starting with the nonlocal keyword!

PYTHON
x = 0

def outer():
    def inner():
        nonlocal x  # Error: x is global, not in an enclosing function
        x += 1

Here, x is global, so nonlocal cannot reach it.

 

Error #3: Declaring nonlocal too early

This is another error we find too often: you must always declare nonlocal before using a parent variable.

PYTHON
def outer():
    val = 10
    def inner():
        val = 20  # masks the variable from the enclosing function
        nonlocal val  # ❌ Error: incorrect order
        val += 1

 

Limitations of nonlocal

Although practical, nonlocal has strict restrictions to know.

Limitation #1: It requires a nested function

We've already seen this together, you must imperatively be in a nested function.

PYTHON
# This doesn't work
nonlocal x  # ❌ SyntaxError
Good to know

The nonlocal keyword does not apply to global variables. For that, you must use global.

 

Limitation #2: No multiple declaration

Unlike global, you cannot combine multiple names with a single declaration.

This is therefore not possible:

PYTHON
# ❌ Error
nonlocal x, y  # forbidden

Each variable must be declared one by one.

 

Frequently asked questions about the nonlocal keyword

Here are the most frequent questions when starting with the nonlocal keyword. 🥸

Question

Can you combine nonlocal and global?

No. A variable cannot be both global and nonlocal. This would generate a scope error.

 

Question

Can you use it in a class?

Not directly. Classes have their own scope model. Use instance attributes instead (with self.var therefore) or nested closures in methods if necessary.

 

Question

Does nonlocal slow down code execution?

No! Its impact is almost zero in terms of performance.

 

Question

How to properly learn Python?

You can follow a completely up-to-date training on the latest Python features by clicking here.

Related terms

Discover our python glossary

Browse the terms and definitions most commonly used in development with Python.

Share this article

Want to help us? Share this article on your networks or even better: on your site, in an article or in your newsletter.