Search code examples
pythonattributesmember-variables

What is the difference between class and instance attributes?


Is there any meaningful distinction between:

class A(object):
    foo = 5   # some default value

vs.

class B(object):
    def __init__(self, foo=5):
        self.foo = foo

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?


Solution

  • 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    
    []