Don't understand why UnboundLocalError occurs (closure)

186

What am I doing wrong here?

counter = 0

def increment():
  counter += 1

increment()

The above code throws an UnboundLocalError.

This question is tagged with python scope closures global-variables

~ Asked on 2012-02-13 17:11:38

The Best Answer is


181

Python doesn't have variable declarations, so it has to figure out the scope of variables itself. It does so by a simple rule: If there is an assignment to a variable inside a function, that variable is considered local.[1] Thus, the line

counter += 1

implicitly makes counter local to increment(). Trying to execute this line, though, will try to read the value of the local variable counter before it is assigned, resulting in an UnboundLocalError.[2]

If counter is a global variable, the global keyword will help. If increment() is a local function and counter a local variable, you can use nonlocal in Python 3.x.

~ Answered on 2012-02-13 17:15:54


87

You need to use the global statement so that you are modifying the global variable counter, instead of a local variable:

counter = 0

def increment():
  global counter
  counter += 1

increment()

If the enclosing scope that counter is defined in is not the global scope, on Python 3.x you could use the nonlocal statement. In the same situation on Python 2.x you would have no way to reassign to the nonlocal name counter, so you would need to make counter mutable and modify it:

counter = [0]

def increment():
  counter[0] += 1

increment()
print counter[0]  # prints '1'

~ Answered on 2012-02-13 17:13:58


Most Viewed Questions: