pythonclosuresglobalnested-functionpython-nonlocal

What does "nonlocal" do in Python 3?


What does nonlocal do in Python 3.x?


To close debugging questions where OP needs nonlocal and doesn't realize it, please use Is it possible to modify variable in python that is in outer, but not global, scope? instead.

Although Python 2 is officially unsupported as of January 1, 2020, if for some reason you are forced to maintain a Python 2.x codebase and need an equivalent to nonlocal, see nonlocal keyword in Python 2.x.


Solution

  • Compare this, without using nonlocal:

    x = 0
    def outer():
        x = 1
        def inner():
            x = 2
            print("inner:", x)
    
        inner()
        print("outer:", x)
    
    outer()
    print("global:", x)
    
    # inner: 2
    # outer: 1
    # global: 0
    

    To this, using nonlocal, where inner()'s x is now also outer()'s x:

    x = 0
    def outer():
        x = 1
        def inner():
            nonlocal x
            x = 2
            print("inner:", x)
    
        inner()
        print("outer:", x)
    
    outer()
    print("global:", x)
    
    # inner: 2
    # outer: 2
    # global: 0
    

    If we were to use global, it would bind x to the properly "global" value:

    x = 0
    def outer():
        x = 1
        def inner():
            global x
            x = 2
            print("inner:", x)
            
        inner()
        print("outer:", x)
    
    outer()
    print("global:", x)
    
    # inner: 2
    # outer: 1
    # global: 2