This question already has an answer here:
What am I doing wrong here?
counter = 0
def increment():
counter += 1
increment()
The above code throws an UnboundLocalError
.
This question already has an answer here:
What am I doing wrong here?
counter = 0
def increment():
counter += 1
increment()
The above code throws an UnboundLocalError
.
You need to use the global statement so that you are modifying the global variable counter, instead of a local variable:
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 namecounter
, so you would need to makecounter
mutable and modify it:To modify a global variable inside a function, you must use the global keyword.
When you try to do this without the line
inside of the definition of increment, a local variable named counter is created so as to keep you from mucking up the counter variable that the whole program may depend on.
Note that you only need to use global when you are modifying the variable; you could read counter from within increment without the need for the global statement.
Python has lexical scoping by default, which means that although an enclosed scope can access values in its enclosing scope, it cannot modify them (unless they're declared global with the
global
keyword).A closure binds values in the enclosing environment to names in the local environment. The local environment can then use the bound value, and even reassign that name to something else, but it can't modify the binding in the enclosing environment.
In your case you are trying to treat
counter
as a local variable rather than a bound value. Note that this code, which binds the value ofx
assigned in the enclosing environment, works fine:The reason of why your code throws an
UnboundLocalError
is already well explained in other answers.But it seems to me that you're trying to build something that works like
itertools.count()
.So why don't you try it out, and see if it suits your case:
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
implicitly makes
counter
local toincrement()
. Trying to execute this line, though, will try to read the value of the local variablecounter
before it is assigned, resulting in anUnboundLocalError
.[2]If
counter
is a global variable, theglobal
keyword will help. Ifincrement()
is a local function andcounter
a local variable, you can usenonlocal
in Python 3.x.Python is not purely lexically scoped.
See this: Using global variables in a function other than the one that created them
and this: http://www.saltycrane.com/blog/2008/01/python-variable-scope-notes/