Search code examples
pythonpython-3.xfunctional-programmingclosuresnested-function

How to modify local variables from a nested closure?


Consider the following code example:

def testClosure():
    count = 0

    def increment():
        count += 1

    for i in range(10):
        increment()

    print(count)    

Calling this results in:

Traceback (most recent call last):
  File "/Users/cls/workspace/PLPcython/src/sandbox.py", line 23, in <module>
    testClosure()
  File "/Users/cls/workspace/PLPcython/src/sandbox.py", line 18, in testClosure
    increment()
  File "/Users/cls/workspace/PLPcython/src/sandbox.py", line 15, in increment
    count += 1
UnboundLocalError: local variable 'count' referenced before assignment

I am used to code like this working in C++:

void testClosure() {
    int count = 0

    auto increment = [&](){
        count += 1;
    };

    for (int i = 0; i < 10; ++i) {
        increment();
    }

}

What am I doing wrong? Is it not possible to modify local variables of the outer function from an inner function? Are these different types of closures (Python vs C++)?


Solution

  • I got it working if you do this:

    def testClosure():
        count = 0
    
        def increment():
            nonlocal count
            count += 1
    
        for i in range(10):
            increment()
    
        print(count)
    testClosure()
    

    Note this will only work in Python 3.x, but you are clearly using that so it isn't a problem.