Reputation: 65
This may be a very stupid question, but I'm a little uncertain as to why lists behave differently to other variables in Python 3, with regard to scope. In the following code...
foo = 1
bar = [1,2,3,4]
def baz():
foo += 1
bar[0]+=1
I understand why foo += 1
throws an error with regard to foo
being outside of local scope. Why doesn't bar[0]+=1
throw the same error though?
Upvotes: 3
Views: 530
Reputation: 239473
When you execute the code, you will get
....
foo += 1
UnboundLocalError: local variable 'foo' referenced before assignment
foo += 1
is actually evaluated like this. foo = foo + 1
. So, you are adding 1
to the value of foo
and storing it in a variable foo
. Since there is an assignment happening, Python assumes that foo
is a local variable. But, if it is a local variable, in the expression foo + 1
, what would be the value of foo
? Python couldn't answer this question. That is why it throws that error.
But, when you do bar[0] += 1
, Python evaluates it like this bar[0] = bar[0] + 1
. Since, it already knows what bar
is, and you are just trying to replace the first element in it, it allows it. In the last case, we were creating a new local variable called foo
by doing foo += 1
, but here, we are just altering the same object. So Python allows this.
Upvotes: 1
Reputation: 3023
In python, you can't modify globals without the 'global' keyword. This is for clarity.
foo=1
def bar():
global foo
foo=2
bar()
#foo is now 2!
Since bar[0]+=foo modifies the an element of a list, not the value of the list variable itself, it is legal.
Upvotes: 2
Reputation: 47609
The variable foo
points to an object (an integer). The variable baz
points to an object (a list). If you try and reassign baz
to another object you would get the error. But you're not, you're just calling a method on the list object, and anyone can do that.
Upvotes: 2