Both versions are the same (see transcript of tests at the end of this answer), but note that (a) in no case is bar same for all instances of Foo .
An instance is currently being created, when reading bar in the instance, the value in Foo will be read, and the assignments of Foo.bar will be displayed in the instance until instance.bar is assigned. At this point, the destination instance has its own entry __dict__ , which is completely independent of the class.
In [62]: class Foo: pass In [63]: Foo.bar = 1 In [64]: Foo.bar Out[64]: 1 In [65]: f = Foo() In [66]: f.bar Out[66]: 1 In [67]: f.bar +=1 In [68]: f.bar Out[68]: 2 In [69]: Foo.bar Out[69]: 1 In [70]: Foo.bar +=3 In [71]: Foo.bar Out[71]: 4 In [72]: g = Foo() In [73]: g.bar Out[73]: 4 In [74]: class Qux: bar = 1 In [75]: Qux.bar Out[75]: 1 In [76]: q = Qux() In [77]: q.bar Out[77]: 1 In [78]: q.bar+=1 In [79]: q.bar Out[79]: 2 In [80]: Qux.bar Out[80]: 1 In [81]: Qux.bar +=1 In [82]: r = Qux() In [83]: r.bar Out[83]: 2 In [84]: q.bar Out[84]: 2 In [85]: s = Qux() In [87]: s.__dict__ Out[87]: {} In [88]: q.__dict__ Out[88]: {'bar': 2} In [89]: Qux.bar = 'foo' In [90]: Qux.bar Out[90]: 'foo' In [91]: s.bar Out[91]: 'foo'
source share