I was playing around with Python classes and arrived at the following example in which two variables which appear to be static class variables have different behavior when modified.
What's going on here? My first instinct is that something tricky is going on with references.
class Foo:
a = []
n = 0
def bar(self):
self.a.append('foo')
self.n += 1
x = Foo()
print x.a, x.n ([] 0)
x.bar()
print x.a, x.n (['foo', 1])
y = Foo()
print y.a, y.n (['foo', 0])
y.bar()
print y.a, y.n (['foo', 'foo'], 1)
You are correct - in the case of
Foo.a
accessingself.a
actually accessesFoo.a
, which is shared between all instances ofFoo
. However, when you updateself.n
with+=
you actually create an instance-level variable onself
that shadowsFoo.n
:In other words, when you do
self.a.append('some value')
the interpreter fetchesa
from memory via a name onFoo
and then mutates the list thatFoo.a
points to.On the other hand, when you do
self.n += 1
the interpreter:n
fromFoo
(because it can't findn
onself
)n + 1
n
onself