How are Python instance variables different from standard variables? Are they the same thing as data attributes? And what are data attributes? And what do kids on a school trip have got to do with all of this?
Questions, questions and more questions. Understanding instance variables in Python tends to happen in stages. First, you don’t understand what they are. Then, you understand them. Next, you realise that you actually don’t understand instance variables after all. And finally, you’ll get back to understanding them.
More seriously, I recently came across the concept of the four stages of competence which are:
- Unconscious incompetence
- Conscious incompetence
- Conscious competence
- Unconscious competence
If you’re reading this blog, you can’t be in Stage 1 as you know that instance variables exist and that they’re important. You’re likely to be in Stage 2. Let’s try to move up to Stage 3 by answering the questions above.
Python Instance Variables, Data Attributes
I know you already know what a variable is. But bear with me while I set the scene for instance variables by describing variables first.
If you picture the computer program as a room where everything happens, then variables are boxes you place on a shelf in which you store the information you’ll need in the program. The box has a label on its outside. This is the variable name. The data you want to store is placed inside the box.
author_name = "Stephen"
Therefore, this assignment creates a box labelled author_name
and stores the string containing the letters of my name in the box. So, from now on, when you use the name author_name
, the program fetches the contents of this box.
Now let’s assume you created your own class:
class SchoolKid: # Code to define class goes here
Just as you can create an object of type str
, as you did with author_name
, you can create an object of type SchoolKid
:
bob = SchoolKid()
Therefore, you now have a box with the label bob
, and the content of this box is a SchoolKid()
–an object of type SchoolKid
, that is, and not a real school kid, which you shouldn’t place in a box. Thought I should put this warning in, just in case!
Let’s get to the instance variable part now
Let’s add the __init__()
method to SchoolKid
. We’ll keep it simple:
class SchoolKid: def __init__(self): self.name = "Robert" self.lunch = "Cheese sandwich"
This is not a useful class definition as you’re unlikely to want all SchoolKid
s to be called Robert and to eat a cheese sandwich. But this will do for now.
The __init__()
method is called whenever you create an instance of the class, for example when you write bob = SchoolKid()
.
self.name = "Robert"
is an assignment which is similar to the earlier assignment author_name = "Stephen"
. Therefore, the program will create a box labelled name
, and it stores the string "Robert"
in this box.
However, there’s also a box called bob
in the program. The box labelled name
is stored inside the box labelled bob
. The variable name
is not a standalone variable. It’s not a box that exists by itself. name
is an instance variable. This means it’s a variable that belongs to the instance you’ve created. In this case, the instance you created is called bob
. Therefore the instance variable name
belongs to bob
.
How about data attributes
Data attributes and instance variables are the same thing. Next topic.
But, before we move to the next section, let’s use the two terms to help us understand Python’s instance variables better. Or is it understanding Python’s data attributes?
The Python documentation calls these data attributes of an instance object. The term instance variable is a more general term and one used in other programming languages. Both terms make sense. Let’s see why.
You’ve seen how an instance variable is a variable that belongs to an instance of the class. Hence the name instance variable.
In object-oriented programming, attributes are the properties that an object of a certain class or type has. There are two types of attributes that a Python class can have:
- data that belongs to the object, such as
name
andlunch
in the example above. These are data attributes. They’re attributes that consist of data. - actions that the object can do. These are functions. Functions that belong to a class are called methods.
Therefore, the instance variables are the attributes that store data, and not the ones that perform actions.
This blog post is about instance variables, which you now know are also called data attributes, and not about methods. So I won’t talk about methods further in this post. Look out for a future post on these. Or you can read a more detailed introduction to object-oriented programming.
Years 5, 6, And 7 Go On A School Trip
Let’s look at an, ahem, real-life situation. Three year groups in the local school went on a school trip. However, the three teachers took a different approach to organise the logistics for the school trip.
Year 5 and standalone variables
Before setting off in the morning, the Year 5 teacher asked all the students to bring their lunches to the front of the class. Each child’s lunch was in a lunch box, and the teacher labelled each box with the child’s name: roberts_lunch
, marys_lunch
, and so on.
Each lunch was stored in a single variable.
Year 6 and dictionaries
The Year 6 teacher had a different approach. She had a large box divided in compartments. Each compartment had a label with each child’s name on it. The teacher put each of the children’s lunches in the compartment labelled with their names.
This is the dictionary approach. There’s one large lunches
box with many labelled compartments within it:
lunches = { "Robert": "Cheese sandwich", "Mary": "Tuna sandwich", # and so on }
At lunchtime, the Year 6 class was significantly more organised than the Year 5 as the teacher could find the children’s lunches more efficiently and quickly. The kids got to start eating their lunch quicker than the Year 5 ones, and they were less likely to get the wrong lunch, too!
Year 7 and instance variables
Let’s look at the Year 7 class now. The day before the trip, the teacher asked the students to bring a small backpack with them and place their lunch in the backpack. “Keep the backpack on your back at all times”, the teacher reminded the students on their way out of the school to go on the trip.
Each child had a backpack with their lunchbox inside. Each child was therefore carrying his or her own lunch.
To use the class definition from above, each SchoolKid()
now has an instance variable called lunch
. We could make a few changes and additions to the class definition to make things clearer:
class SchoolKid: def __init__(self, child_name, lunch): self.name = child_name self.lunch = lunch def eat_lunch(self): # Code for self to eat his or her lunch, which is self.lunch
And at lunchtime, all the teacher had to do was the following:
for each_child in year_7: each_child.eat_lunch()
each_child
is an object of type SchoolKid
, and eat_lunch()
is a method of the class SchoolKid
.
Year 7 got to start eating their lunches the quickest, and there were no complaints that Robert ate Mary’s lunch by mistake!
Final Words
Understanding Python instance variables is not something that happens in one step. Object-oriented programming is one of those subjects that needs several ‘passes’ before you can truly understand it.
And the key to understanding these topics is to get an intuitive understanding of them. This is something that comes with practice, but a good analogy can help too. Next time you want to picture what’s an instance variable, think of the school kids carrying their lunch in their own backpack!
An object carries its data attributes with it wherever it goes. This is one of the key principles of object-oriented programming.
Further reading
- Understanding Python instance variables and classes in Python: An Introduction to Object-Oriented Programming on The Python Coding Book (Chapter 7)
- More on Object-Oriented Programming on Real Python
- Understanding Programming with The White Room analogy
Become a Member of
The Python Coding Place
Video courses, live cohort-based courses, workshops, weekly videos, members’ forum, and more…
Subscribe to
The Python Coding Stack
Regular articles for the intermediate Python programmer or a beginner who wants to “read ahead”
[…] with the line ball.ball_speed = 0.5. If you want to brush up on this topic, you can read more about Python instance variables. Each ball will have its own speed as balls will speed up or slow down at different […]