Python class variable int vs array

2019-02-17 12:02发布

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)

标签: python class
1条回答
ゆ 、 Hurt°
2楼-- · 2019-02-17 12:39

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
查看更多
登录 后发表回答