low mumble. A lined arrow pointing to the left all

Instance variables vs class attributes

I'm tip-toeing my way toward understanding classes in Python. Today's lesson: the difference between class attributes and instance attributes. There are a few things here.

First, and important to understand, the actual state of class attributes—declared at the top of the class, not inside the __init__ method—are shared across all instances. Here's an example.

class Counter:
    count = 0

    def print_count(self):
        print(self.count)

counter1 = Counter()
counter2 = Counter()

Counter.count = 5
counter1.print_count()  # prints 5
counter2.print_count()  # prints 5

To create an instance attribute that cannot be modified through the parent class, you can declare count in the __init__ method, like so.

class Counter:
    def __init__(self):
        self.count = 0  # creates instance attribute `count`

    def print_count(self):
        print(self.count)

counter1 = Counter()
counter2 = Counter()

Counter.count = 5       # creates a class attribute `count`
counter1.print_count()  # prints 0 since the instance attribute is prioritized

counter1.count = 5
counter1.print_count()  # prints 5
counter2.print_count()  # prints 0

As described in the example, a call to self.count will first look for instance variables, then look for class variables. So working with this prioritization is a good way to protect your attributes.