What is the difference between class and instance attributes? What is the difference between class and instance attributes? python python

What is the difference between class and instance attributes?


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


The difference is that the attribute on the class is shared by all instances. The attribute on an instance is unique to that instance.

If coming from C++, attributes on the class are more like static member variables.


Here is a very good post, and summary it as below.

class Bar(object):    ## No need for dot syntax    class_var = 1    def __init__(self, i_var):        self.i_var = i_var## Need dot syntax as we've left scope of class namespaceBar.class_var## 1foo = MyClass(2)## Finds i_var in foo's instance namespacefoo.i_var## 2## Doesn't find class_var in instance namespace…## So look's in class namespace (Bar.__dict__)foo.class_var## 1

And in visual form

enter image description here

Class attribute assignment

  • If a class attribute is set by accessing the class, it will override the value for all instances

    foo = Bar(2)foo.class_var## 1Bar.class_var = 2foo.class_var## 2
  • If a class variable is set by accessing an instance, it will override the value only for that instance. This essentially overrides the class variable and turns it into an instance variable available, intuitively, only for that instance.

    foo = Bar(2)foo.class_var## 1foo.class_var = 2foo.class_var## 2Bar.class_var## 1

When would you use class attribute?

  • Storing constants. As class attributes can be accessed as attributes of the class itself, it’s often nice to use them for storing Class-wide, Class-specific constants

    class Circle(object):     pi = 3.14159     def __init__(self, radius):          self.radius = radius       def area(self):         return Circle.pi * self.radius * self.radiusCircle.pi## 3.14159c = Circle(10)c.pi## 3.14159c.area()## 314.159
  • Defining default values. As a trivial example, we might create a bounded list (i.e., a list that can only hold a certain number of elements or fewer) and choose to have a default cap of 10 items

    class MyClass(object):    limit = 10    def __init__(self):        self.data = []    def item(self, i):        return self.data[i]    def add(self, e):        if len(self.data) >= self.limit:            raise Exception("Too many elements")        self.data.append(e) MyClass.limit ## 10