Home Interests Python

Class Vs. Instance Variables in Python 3

howchoo
howchoo   (467)
November 22, 2023
14 minutes

Share

Interests
Posted in these interests:
code • 11 guides
python • 18 guides

When learning object oriented programming in Python, there can be a few gotchas when it comes to distinguishing between class and instance variables. In this guide I’ll explain the difference between class and instance variables and provide examples demonstrating various use cases.

1 – Class vs. instance variables

First, a quick review if you’re new to object-oriented programming. A class is a template for creating objects, and an instance is the object itself. Classes often represent something in the real world, so imagine if you wanted to represent a classroom full of students. You might create a class called Student, which is a template that defines various attributes of a student. Each student, then, is an instance of the Student class.

When dealing with any sort of data, some attributes are going to be unique and some will be shared. Consider our student example, each student in this classroom has the same room number and the same teacher, but they each have a unique name, age, and favorite subject.

Class variables

Class variables are usually variables that are shared by all instances. And they are defined like this:

class Student:
    teacher = 'Mrs. Jones'  # class variable

Each instance of the class will have the same value for these variables:

tom = Student()
susan = Student()

print(tom.teacher)
>> "Mrs. Jones"

print(susan.teacher)
>> "Mrs. Jones"

Instance variables

Instance variables (also called data attributes) are unique to each instance of the class, and they are defined within a class method, like this:

class Student:
    teacher = 'Mrs. Jones'  # class variable

    def __init__(self, name):
        self.name = name  # instance variable

See how each instance now contains a unique value for name:

tom = Student('Tom')
susan = Student('Susan')

print(tom.name)
>> "Tom"

print(susan.name)
>> "Susan"

Summary

This was only a basic overview of class and instance variables. We’ll go into more depth in the upcoming steps, but the most important takeaway is that class variables are typically used for values that are shared among all instances of a class while instance variables are used for values that are unique to each instance.

2 – What to expect from class variables

Class variables are shared among all instances of a class. As a reminder, they are defined like this:

class Student:
    teacher = 'Mrs. Jones'  # class variable

Said another way, class variables reference the same location in memory. See the following:

tom = Student()
susan = Student()

id(tom.teacher) == id(susan.teacher)
>> True

Note: The id function returns the address of the object in memory for the CPython implementation.

So with the id function we can confirm that the teacher attribute refers to the same location in memory.

3 – Modifying a class variable

What happens if we modify a class variable even after we’ve created instances?

tom = Student()

tom.teacher                                                                                                                                                                      
>> Mrs. Jones

Student.teacher = 'Mr. Smith'                                                                                                                                                    

tom.teacher                                                                                                                                                                      
>> Mr. Smith

As you might expect, because the teacher variable refers to a shared location in memory, it is updated on the instance as well.

4 – Modifying an instance variable

This is probably the most obvious and expected behavior, so feel free to skip past this step. But I will still show a few examples for completeness.

Consider our Student class with both class and instance variables:

class Student:
    teacher = 'Mrs. Jones'  # class variable

    def __init__(self, name):
        self.name = name  # instance variable

We can see that each instance of the class has a unique memory address for name:

tom = Student('Tom')
susan = Student('Susan')

id(tom.name) == id(susan.name)
>> False

So as you might expect, updating the name attribute on one instance has no effect on the other:

tom,name
>> Tom

susan.name
>> Susan

tom.name = 'Thomas'
tom.name
>> Thomas

susan.name
>> Susan

5 – Instance variables override class variables (and methods)

It is important to note that instance variables (or data attributes) override class variables.

Remember the following?

tom = Student()
susan = Student()

id(tom.teacher) == id(susan.teacher)
>> True

What happens if we change the teacher attribute directly on one of the instances:

tom.teacher = 'Mr. Clark'

This is important to note: instance variables need not be declared, they are created whenever they are assigned, and instance variables override class variables. This means, on the tom instance, teacher no longer refers to the class variable, but rather a newly created instance variable.

And naturally, the susan instance is not affected:

tom.teacher  # instance variable
>> Mr. Clark

susan.teacher  # class variable
>> Mrs. Jones

Hopefully, you see how this behavior can lead to confusion. For this reason, it is important to keep variable names organized. If a variable is declared as a class variable, it should (usually) not be overridden. Instance variables can be defined in obvious places, like the __init__ method. It’s often good to come up with a naming convention for variables. For example, class methods should be verbs, class variables nouns, and instance variables nouns prefixed with an “_”.

6 – Using mutable objects as class variables

Related to the previous step, beware when using mutable objects as class variables. You might be surprised by the behavior.

Imagine we want a list of the student’s test scores. We might compose a class like this:

class Student:
    teacher = 'Mrs. Jones'
    test_scores = []

    def __init__(self, name):
        self.name = name

    def add_score(self, score):
        self.test_scores.append(score)

We’ve got a class variable to hold the scores, and we’ve got a class method for adding scores. Now let’s add some scores.

tom = Student('Tom')
susan = Student('Susan')

tom.add_score(90)
susan.add_score(100)

Can you guess what mistake we just made?

tom.test_scores
>> [90, 100]

Yep, test_scores is a class variable, not an instance variable. Each instance is simply appending values to the class variable. What we really want is for each instance to hold its own list of test_scores.

So a better class might look like this:

class Student:
    teacher = 'Mrs. Jones'

    def __init__(self, name):
        self.name = name
        self.test_scores = []

    def add_score(self, score):
        self.test_scores.append(score)

And now our problem is solved!

7 – Conclusion

Hopefully you’ve learned the difference between class and instance variables and what to expect from each. If I’m missing something in this guide or if you have any great examples of class and instance variable confusion, please comment below. I’d be happy to add them to this guide!

NEXT UP

Secure Your Sensitive Data with Kubernetes Secrets

Learn how to create and use Kubernetes secrets.
howchoo   (467)
November 26, 2023

Kubernetes secrets are objects that store and manage sensitive data inside your Kubernetes cluster. One mistake developers often make is storing sensitive information like database passwords, API credentials, etc in a settings file in their codebase. This is very bad practice (hopefully for obvious reasons). Most developers know this, but still choose the option because it’s easy.

Continue Reading

howchoo

 467 guides

Introducing Howchoo, an enigmatic author whose unique pen name reflects their boundless curiosity and limitless creativity. Mysterious and multifaceted, Howchoo has emerged as a captivating storyteller, leaving readers mesmerized by the uncharted realms they craft with their words. With an insatiable appetite for knowledge and a love for exploration, Howchoo's writing transcends conventional genres, blurring the lines between fantasy, science fiction, and the surreal. Their narratives are a kaleidoscope of ideas, weaving together intricate plots, unforgettable characters, and thought-provoking themes that challenge the boundaries of imagination.

Discover interesting things!

Explore Howchoo's most popular interests.

Explore