Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python class variable int vs array

Tags:

python

class

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)
like image 592
mcamac Avatar asked May 29 '13 04:05

mcamac


1 Answers

You are correct - in the case of Foo.a accessing self.a actually accesses Foo.a, which is shared between all instances of Foo. However, when you update self.n with += you actually create an instance-level variable on self that shadows Foo.n:

>>> import dis
>>> dis.dis(Foo.bar)
  5           0 LOAD_FAST                0 (self)
              3 LOAD_ATTR                0 (a)
              6 LOAD_ATTR                1 (append)
              9 LOAD_CONST               1 ('foo')
             12 CALL_FUNCTION            1
             15 POP_TOP             

  6          16 LOAD_FAST                0 (self)
             19 DUP_TOP             
             20 LOAD_ATTR                2 (n)
             23 LOAD_CONST               2 (1)
             26 INPLACE_ADD         
             27 ROT_TWO             
             28 STORE_ATTR               2 (n)
             31 LOAD_CONST               0 (None)
             34 RETURN_VALUE    

In other words, when you do self.a.append('some value') the interpreter fetches a from memory via a name on Foo and then mutates the list that Foo.a points to.

On the other hand, when you do self.n += 1 the interpreter:

  • Fetches n from Foo (because it can't find n on self)
  • Creates a new value n + 1
  • Stores the new value in the attribute n on self
like image 178
Sean Vieira Avatar answered Nov 01 '22 20:11

Sean Vieira