<p>Is there any meaningful distinction between:</p>

<pre><code>class A(object):
    foo = 5   # some default value
</code></pre>

<p>vs.</p>

<pre><code>class B(object):
    def __init__(self, foo=5):
        self.foo = foo
</code></pre>

<p>If you're creating a lot of instances, is there any difference in performance or space requirements for the two styles? When you read the code, do you consider the meaning of the two styles to be significantly different?</p>

There is a significant
semantic
difference (beyond performance considerations):
when the attribute is defined on the instance
(which is what we usually do), there can be multiple objects referred to.
Each gets a totally separate version of that attribute
.
when the attribute is defined on the class
, there is only one underlying object referred to, so if operations on different instances of that class both attempt to set/(append/extend/insert/etc.) the attribute, then:
if the attribute is a
builtin type
(like int, float, boolean, string), operations on one object will overwrite (clobber) the value
if the attribute is a
mutable type
(like a list or a dict), we will get unwanted leakage.
For example:
```
```
>>> class A: foo = []
>>> a, b = A(), A()
>>> a.foo.append(5)
>>> b.foo
[5]
>>> class A:
...  def __init__(self): self.foo = []
>>> a, b = A(), A()
>>> a.foo.append(5)
>>> b.foo    
[]
```
```