Don't understand why UnboundLocalError occurs [duplicate]
This question already has an answer here:
How to change a variable after it is already defined?
6 answers
Using global variables in a function
18 answers
What am I doing wrong here?
counter = 0
def increment():
counter += 1
increment()
The above code throws an UnboundLocalError
.
python global-variables scope
marked as duplicate by Zero Piraeus
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Dec 29 '16 at 6:42
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
|
show 1 more comment
This question already has an answer here:
How to change a variable after it is already defined?
6 answers
Using global variables in a function
18 answers
What am I doing wrong here?
counter = 0
def increment():
counter += 1
increment()
The above code throws an UnboundLocalError
.
python global-variables scope
marked as duplicate by Zero Piraeus
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Dec 29 '16 at 6:42
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
41
@ZeroPiraeus: why did you hammer a question with 40k+ views, which is the first result for "UnboundLocalError" in Google, as a duplicate of a nearly identical new question that you answered instead of simply posting your answer here?
– vaultah
Jan 3 '17 at 0:26
1
This question and the one it's currently marked duplicate of are under discussion in the Python chatroom.
– Zero Piraeus
Jan 3 '17 at 1:30
4
Many of the answers here say to useglobal
, and although that works, using modifiable globals is generally not recommend when other options exist.
– PM 2Ring
Jan 3 '17 at 1:34
10
@ZeroPiraeus A question asked in 2012 can't be a duplicate of a question asked in 2016 ... rather the newer one is the duplicate.
– dsh
Feb 14 '17 at 17:04
5
@dsh That's not true.
– Zero Piraeus
Feb 14 '17 at 18:03
|
show 1 more comment
This question already has an answer here:
How to change a variable after it is already defined?
6 answers
Using global variables in a function
18 answers
What am I doing wrong here?
counter = 0
def increment():
counter += 1
increment()
The above code throws an UnboundLocalError
.
python global-variables scope
This question already has an answer here:
How to change a variable after it is already defined?
6 answers
Using global variables in a function
18 answers
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:
How to change a variable after it is already defined?
6 answers
Using global variables in a function
18 answers
python global-variables scope
python global-variables scope
edited Nov 20 '18 at 23:00
martineau
68.9k1091186
68.9k1091186
asked Feb 13 '12 at 17:11
RandomblueRandomblue
36.2k119287505
36.2k119287505
marked as duplicate by Zero Piraeus
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Dec 29 '16 at 6:42
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by Zero Piraeus
StackExchange.ready(function() {
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function() {
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function() {
$hover.showInfoMessage('', {
messageElement: $msg.clone().show(),
transient: false,
position: { my: 'bottom left', at: 'top center', offsetTop: -7 },
dismissable: false,
relativeToBody: true
});
},
function() {
StackExchange.helpers.removeMessages();
}
);
});
});
Dec 29 '16 at 6:42
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
41
@ZeroPiraeus: why did you hammer a question with 40k+ views, which is the first result for "UnboundLocalError" in Google, as a duplicate of a nearly identical new question that you answered instead of simply posting your answer here?
– vaultah
Jan 3 '17 at 0:26
1
This question and the one it's currently marked duplicate of are under discussion in the Python chatroom.
– Zero Piraeus
Jan 3 '17 at 1:30
4
Many of the answers here say to useglobal
, and although that works, using modifiable globals is generally not recommend when other options exist.
– PM 2Ring
Jan 3 '17 at 1:34
10
@ZeroPiraeus A question asked in 2012 can't be a duplicate of a question asked in 2016 ... rather the newer one is the duplicate.
– dsh
Feb 14 '17 at 17:04
5
@dsh That's not true.
– Zero Piraeus
Feb 14 '17 at 18:03
|
show 1 more comment
41
@ZeroPiraeus: why did you hammer a question with 40k+ views, which is the first result for "UnboundLocalError" in Google, as a duplicate of a nearly identical new question that you answered instead of simply posting your answer here?
– vaultah
Jan 3 '17 at 0:26
1
This question and the one it's currently marked duplicate of are under discussion in the Python chatroom.
– Zero Piraeus
Jan 3 '17 at 1:30
4
Many of the answers here say to useglobal
, and although that works, using modifiable globals is generally not recommend when other options exist.
– PM 2Ring
Jan 3 '17 at 1:34
10
@ZeroPiraeus A question asked in 2012 can't be a duplicate of a question asked in 2016 ... rather the newer one is the duplicate.
– dsh
Feb 14 '17 at 17:04
5
@dsh That's not true.
– Zero Piraeus
Feb 14 '17 at 18:03
41
41
@ZeroPiraeus: why did you hammer a question with 40k+ views, which is the first result for "UnboundLocalError" in Google, as a duplicate of a nearly identical new question that you answered instead of simply posting your answer here?
– vaultah
Jan 3 '17 at 0:26
@ZeroPiraeus: why did you hammer a question with 40k+ views, which is the first result for "UnboundLocalError" in Google, as a duplicate of a nearly identical new question that you answered instead of simply posting your answer here?
– vaultah
Jan 3 '17 at 0:26
1
1
This question and the one it's currently marked duplicate of are under discussion in the Python chatroom.
– Zero Piraeus
Jan 3 '17 at 1:30
This question and the one it's currently marked duplicate of are under discussion in the Python chatroom.
– Zero Piraeus
Jan 3 '17 at 1:30
4
4
Many of the answers here say to use
global
, and although that works, using modifiable globals is generally not recommend when other options exist.– PM 2Ring
Jan 3 '17 at 1:34
Many of the answers here say to use
global
, and although that works, using modifiable globals is generally not recommend when other options exist.– PM 2Ring
Jan 3 '17 at 1:34
10
10
@ZeroPiraeus A question asked in 2012 can't be a duplicate of a question asked in 2016 ... rather the newer one is the duplicate.
– dsh
Feb 14 '17 at 17:04
@ZeroPiraeus A question asked in 2012 can't be a duplicate of a question asked in 2016 ... rather the newer one is the duplicate.
– dsh
Feb 14 '17 at 17:04
5
5
@dsh That's not true.
– Zero Piraeus
Feb 14 '17 at 18:03
@dsh That's not true.
– Zero Piraeus
Feb 14 '17 at 18:03
|
show 1 more comment
8 Answers
8
active
oldest
votes
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.
5
python 3 docs has a faq page on why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value via unboundlocalerror-local-variable-l-referenced-before-assignment-python
– here
May 4 '14 at 7:19
A note that caught me out, I had a variable declared at the top of the file that I can read inside a function without issue, however to write to a variable that I have declared at the top of the file, I had to use global.
– mouckatron
Feb 6 '18 at 14:35
A more in-depth explanation: docs.python.org/3.3/reference/…. Not only can assignments bind names, so can imports, so you may also getUnboundLocalError
from a statement that uses an unbounded imported name. Example:def foo(): bar = deepcopy({'a':1}); from copy import deepcopy; return bar
, thenfrom copy import deepcopy; foo()
. The call succeeds if the local importfrom copy import deepcopy
is removed.
– Yibo Yang
Jun 27 '18 at 16:00
add a comment |
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'
add a comment |
To answer the question in your subject line,* yes, there are closures in Python, except they only apply inside a function, and also (in Python 2.x) they are read-only; you can't re-bind the name to a different object (though if the object is mutable, you can modify its contents). In Python 3.x, you can use the nonlocal
keyword to modify a closure variable.
def incrementer():
counter = 0
def increment():
nonlocal counter
counter += 1
return counter
return increment
increment = incrementer()
increment() # 1
increment() # 2
* The original question's title asked about closures in Python.
add a comment |
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:
>>> from itertools import count
>>> counter = count(0)
>>> counter
count(0)
>>> next(counter)
0
>>> counter
count(1)
>>> next(counter)
1
>>> counter
count(2)
add a comment |
To modify a global variable inside a function, you must use the global keyword.
When you try to do this without the line
global counter
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.
add a comment |
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 of x
assigned in the enclosing environment, works fine:
>>> x = 1
>>> def f():
>>> return x
>>> f()
1
add a comment |
try this
counter = 0
def increment():
global counter
counter += 1
increment()
add a comment |
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/
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
– munk
Mar 7 '18 at 19:05
@munk Cool, you realise that this is a link to another answer on SO?
– Marcin
Mar 7 '18 at 20:33
add a comment |
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
5
python 3 docs has a faq page on why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value via unboundlocalerror-local-variable-l-referenced-before-assignment-python
– here
May 4 '14 at 7:19
A note that caught me out, I had a variable declared at the top of the file that I can read inside a function without issue, however to write to a variable that I have declared at the top of the file, I had to use global.
– mouckatron
Feb 6 '18 at 14:35
A more in-depth explanation: docs.python.org/3.3/reference/…. Not only can assignments bind names, so can imports, so you may also getUnboundLocalError
from a statement that uses an unbounded imported name. Example:def foo(): bar = deepcopy({'a':1}); from copy import deepcopy; return bar
, thenfrom copy import deepcopy; foo()
. The call succeeds if the local importfrom copy import deepcopy
is removed.
– Yibo Yang
Jun 27 '18 at 16:00
add a comment |
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.
5
python 3 docs has a faq page on why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value via unboundlocalerror-local-variable-l-referenced-before-assignment-python
– here
May 4 '14 at 7:19
A note that caught me out, I had a variable declared at the top of the file that I can read inside a function without issue, however to write to a variable that I have declared at the top of the file, I had to use global.
– mouckatron
Feb 6 '18 at 14:35
A more in-depth explanation: docs.python.org/3.3/reference/…. Not only can assignments bind names, so can imports, so you may also getUnboundLocalError
from a statement that uses an unbounded imported name. Example:def foo(): bar = deepcopy({'a':1}); from copy import deepcopy; return bar
, thenfrom copy import deepcopy; foo()
. The call succeeds if the local importfrom copy import deepcopy
is removed.
– Yibo Yang
Jun 27 '18 at 16:00
add a comment |
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.
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.
edited Feb 23 '13 at 8:24
Honest Abe
5,45233454
5,45233454
answered Feb 13 '12 at 17:15
Sven MarnachSven Marnach
355k79754697
355k79754697
5
python 3 docs has a faq page on why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value via unboundlocalerror-local-variable-l-referenced-before-assignment-python
– here
May 4 '14 at 7:19
A note that caught me out, I had a variable declared at the top of the file that I can read inside a function without issue, however to write to a variable that I have declared at the top of the file, I had to use global.
– mouckatron
Feb 6 '18 at 14:35
A more in-depth explanation: docs.python.org/3.3/reference/…. Not only can assignments bind names, so can imports, so you may also getUnboundLocalError
from a statement that uses an unbounded imported name. Example:def foo(): bar = deepcopy({'a':1}); from copy import deepcopy; return bar
, thenfrom copy import deepcopy; foo()
. The call succeeds if the local importfrom copy import deepcopy
is removed.
– Yibo Yang
Jun 27 '18 at 16:00
add a comment |
5
python 3 docs has a faq page on why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value via unboundlocalerror-local-variable-l-referenced-before-assignment-python
– here
May 4 '14 at 7:19
A note that caught me out, I had a variable declared at the top of the file that I can read inside a function without issue, however to write to a variable that I have declared at the top of the file, I had to use global.
– mouckatron
Feb 6 '18 at 14:35
A more in-depth explanation: docs.python.org/3.3/reference/…. Not only can assignments bind names, so can imports, so you may also getUnboundLocalError
from a statement that uses an unbounded imported name. Example:def foo(): bar = deepcopy({'a':1}); from copy import deepcopy; return bar
, thenfrom copy import deepcopy; foo()
. The call succeeds if the local importfrom copy import deepcopy
is removed.
– Yibo Yang
Jun 27 '18 at 16:00
5
5
python 3 docs has a faq page on why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value via unboundlocalerror-local-variable-l-referenced-before-assignment-python
– here
May 4 '14 at 7:19
python 3 docs has a faq page on why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value via unboundlocalerror-local-variable-l-referenced-before-assignment-python
– here
May 4 '14 at 7:19
A note that caught me out, I had a variable declared at the top of the file that I can read inside a function without issue, however to write to a variable that I have declared at the top of the file, I had to use global.
– mouckatron
Feb 6 '18 at 14:35
A note that caught me out, I had a variable declared at the top of the file that I can read inside a function without issue, however to write to a variable that I have declared at the top of the file, I had to use global.
– mouckatron
Feb 6 '18 at 14:35
A more in-depth explanation: docs.python.org/3.3/reference/…. Not only can assignments bind names, so can imports, so you may also get
UnboundLocalError
from a statement that uses an unbounded imported name. Example: def foo(): bar = deepcopy({'a':1}); from copy import deepcopy; return bar
, then from copy import deepcopy; foo()
. The call succeeds if the local import from copy import deepcopy
is removed.– Yibo Yang
Jun 27 '18 at 16:00
A more in-depth explanation: docs.python.org/3.3/reference/…. Not only can assignments bind names, so can imports, so you may also get
UnboundLocalError
from a statement that uses an unbounded imported name. Example: def foo(): bar = deepcopy({'a':1}); from copy import deepcopy; return bar
, then from copy import deepcopy; foo()
. The call succeeds if the local import from copy import deepcopy
is removed.– Yibo Yang
Jun 27 '18 at 16:00
add a comment |
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'
add a comment |
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'
add a comment |
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'
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'
edited Feb 13 '12 at 17:20
answered Feb 13 '12 at 17:13
Andrew ClarkAndrew Clark
146k17194255
146k17194255
add a comment |
add a comment |
To answer the question in your subject line,* yes, there are closures in Python, except they only apply inside a function, and also (in Python 2.x) they are read-only; you can't re-bind the name to a different object (though if the object is mutable, you can modify its contents). In Python 3.x, you can use the nonlocal
keyword to modify a closure variable.
def incrementer():
counter = 0
def increment():
nonlocal counter
counter += 1
return counter
return increment
increment = incrementer()
increment() # 1
increment() # 2
* The original question's title asked about closures in Python.
add a comment |
To answer the question in your subject line,* yes, there are closures in Python, except they only apply inside a function, and also (in Python 2.x) they are read-only; you can't re-bind the name to a different object (though if the object is mutable, you can modify its contents). In Python 3.x, you can use the nonlocal
keyword to modify a closure variable.
def incrementer():
counter = 0
def increment():
nonlocal counter
counter += 1
return counter
return increment
increment = incrementer()
increment() # 1
increment() # 2
* The original question's title asked about closures in Python.
add a comment |
To answer the question in your subject line,* yes, there are closures in Python, except they only apply inside a function, and also (in Python 2.x) they are read-only; you can't re-bind the name to a different object (though if the object is mutable, you can modify its contents). In Python 3.x, you can use the nonlocal
keyword to modify a closure variable.
def incrementer():
counter = 0
def increment():
nonlocal counter
counter += 1
return counter
return increment
increment = incrementer()
increment() # 1
increment() # 2
* The original question's title asked about closures in Python.
To answer the question in your subject line,* yes, there are closures in Python, except they only apply inside a function, and also (in Python 2.x) they are read-only; you can't re-bind the name to a different object (though if the object is mutable, you can modify its contents). In Python 3.x, you can use the nonlocal
keyword to modify a closure variable.
def incrementer():
counter = 0
def increment():
nonlocal counter
counter += 1
return counter
return increment
increment = incrementer()
increment() # 1
increment() # 2
* The original question's title asked about closures in Python.
edited Apr 7 '17 at 12:08
Drunken Master
99421026
99421026
answered Feb 13 '12 at 17:21
kindallkindall
129k18194247
129k18194247
add a comment |
add a comment |
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:
>>> from itertools import count
>>> counter = count(0)
>>> counter
count(0)
>>> next(counter)
0
>>> counter
count(1)
>>> next(counter)
1
>>> counter
count(2)
add a comment |
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:
>>> from itertools import count
>>> counter = count(0)
>>> counter
count(0)
>>> next(counter)
0
>>> counter
count(1)
>>> next(counter)
1
>>> counter
count(2)
add a comment |
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:
>>> from itertools import count
>>> counter = count(0)
>>> counter
count(0)
>>> next(counter)
0
>>> counter
count(1)
>>> next(counter)
1
>>> counter
count(2)
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:
>>> from itertools import count
>>> counter = count(0)
>>> counter
count(0)
>>> next(counter)
0
>>> counter
count(1)
>>> next(counter)
1
>>> counter
count(2)
answered Feb 13 '12 at 17:31
Rik PoggiRik Poggi
19.5k54972
19.5k54972
add a comment |
add a comment |
To modify a global variable inside a function, you must use the global keyword.
When you try to do this without the line
global counter
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.
add a comment |
To modify a global variable inside a function, you must use the global keyword.
When you try to do this without the line
global counter
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.
add a comment |
To modify a global variable inside a function, you must use the global keyword.
When you try to do this without the line
global counter
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.
To modify a global variable inside a function, you must use the global keyword.
When you try to do this without the line
global counter
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.
answered Feb 13 '12 at 17:13
chucksmashchucksmash
3,71811938
3,71811938
add a comment |
add a comment |
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 of x
assigned in the enclosing environment, works fine:
>>> x = 1
>>> def f():
>>> return x
>>> f()
1
add a comment |
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 of x
assigned in the enclosing environment, works fine:
>>> x = 1
>>> def f():
>>> return x
>>> f()
1
add a comment |
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 of x
assigned in the enclosing environment, works fine:
>>> x = 1
>>> def f():
>>> return x
>>> f()
1
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 of x
assigned in the enclosing environment, works fine:
>>> x = 1
>>> def f():
>>> return x
>>> f()
1
edited Feb 20 '13 at 6:43
Honest Abe
5,45233454
5,45233454
answered Feb 13 '12 at 17:21
Chris TaylorChris Taylor
37.2k1196142
37.2k1196142
add a comment |
add a comment |
try this
counter = 0
def increment():
global counter
counter += 1
increment()
add a comment |
try this
counter = 0
def increment():
global counter
counter += 1
increment()
add a comment |
try this
counter = 0
def increment():
global counter
counter += 1
increment()
try this
counter = 0
def increment():
global counter
counter += 1
increment()
answered Feb 13 '12 at 17:14
LostsoulLostsoul
9,0422684141
9,0422684141
add a comment |
add a comment |
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/
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
– munk
Mar 7 '18 at 19:05
@munk Cool, you realise that this is a link to another answer on SO?
– Marcin
Mar 7 '18 at 20:33
add a comment |
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/
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
– munk
Mar 7 '18 at 19:05
@munk Cool, you realise that this is a link to another answer on SO?
– Marcin
Mar 7 '18 at 20:33
add a comment |
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/
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/
edited May 23 '17 at 10:31
Community♦
11
11
answered Feb 13 '12 at 17:15
MarcinMarcin
35.6k1288173
35.6k1288173
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
– munk
Mar 7 '18 at 19:05
@munk Cool, you realise that this is a link to another answer on SO?
– Marcin
Mar 7 '18 at 20:33
add a comment |
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
– munk
Mar 7 '18 at 19:05
@munk Cool, you realise that this is a link to another answer on SO?
– Marcin
Mar 7 '18 at 20:33
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
– munk
Mar 7 '18 at 19:05
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. - From Review
– munk
Mar 7 '18 at 19:05
@munk Cool, you realise that this is a link to another answer on SO?
– Marcin
Mar 7 '18 at 20:33
@munk Cool, you realise that this is a link to another answer on SO?
– Marcin
Mar 7 '18 at 20:33
add a comment |
41
@ZeroPiraeus: why did you hammer a question with 40k+ views, which is the first result for "UnboundLocalError" in Google, as a duplicate of a nearly identical new question that you answered instead of simply posting your answer here?
– vaultah
Jan 3 '17 at 0:26
1
This question and the one it's currently marked duplicate of are under discussion in the Python chatroom.
– Zero Piraeus
Jan 3 '17 at 1:30
4
Many of the answers here say to use
global
, and although that works, using modifiable globals is generally not recommend when other options exist.– PM 2Ring
Jan 3 '17 at 1:34
10
@ZeroPiraeus A question asked in 2012 can't be a duplicate of a question asked in 2016 ... rather the newer one is the duplicate.
– dsh
Feb 14 '17 at 17:04
5
@dsh That's not true.
– Zero Piraeus
Feb 14 '17 at 18:03