Distinguishing Instance Variables from Class Variables in python
Ogwuru Johnson Nov 29 '17
In the last article we learnt how to create a class and its instance. Today we would look at the difference between an instance variable and a class variable.
Instance variables are variables used for data that is unique to a particular instance. Example of instance variables are the ones we used in the previous article.
def __init__(self,first,last,pay): self.first = first self.last = last self.pay = pay self.email = first + '.' +last+ '@company.com'
All of this are initialized for each of the unique instances that we would create, this instances in this context are the employees we would create.
Class Variables are variables that are shared by all instances of a class. So while instance variable can be unique for each instance like our name,email and pay; class variable should be the-same for each instance.
Now looking at our (Employee) class in the previous example any data that has to be shared by all instances of the Employee class has to be stored in a class variable so all the instances created can have access to it. An example of such data could be a yearly raise for each employee.
To do this, let's say we create a new method named (apply_raise) and instead of using a class variable we use an instance variable;
class Employee: def __init__(self,first,last,pay): self.first = first self.last = last self.pay = pay def apply_raise(self): self.pay = int(self.pay * 1.04) emp_1 = Employee('John','Son',60000) print (emp_1.pay) emp_1.apply_raise() print(emp_1.pay)
Running this program would give us our desired output; but what if we have a situation where we need to output the raise amount or even update the raise amount. Our (BIG) brains would trickily as us to change the (1.04) rate on the (apply_raise) method, but since we are learning OOP that wouldn't be a nice approach.
We would need to create a class variable to contain the data about the pay raise.
class Employee: raise_amount = 1.04
Now on our (apply_raise) method we would have;
def apply_raise(self): self.pay = int(self.pay * self.raise_amount)
We were able to pass in the (raise_amount) because it's a class variable and can be accessed by all instances within the parent class.
Now if we print the raise amount;
print(Employee.raise_amount) print(emp_1.raise_amount) print(emp_2.raise_amount)
We get the-same output, which proves that class variables could be accessed by your class and at the-same time instances of the class.
So what happens here is that when we try to access an attribute on an instance, it first checks whether the instance contains the attribute; if it doesn't, it checks if the parent class or any class it inherits from contains the attributes; so when we access (raise_amount) from our instances, they don't actually have that attribute but rather they are accessing the classes the (raise_amount) variable attributes.
Another place we could use a (class variable); say we are expected to output the number of employees. Our entire code would now look like this:
class Employee: no_emps = 0 raise_amount = 1.04 def __init__(self,first,last,pay): self.first = first self.last = last self.pay = pay self.email = first + '.' +last+ '@company.com' Employee.no_emps +=1 def fullname(self): return self.first + ' ' + self.last def apply_raise(self): self.pay = int(self.pay * self.raise_amount ) print(Employee.no_emps) emp_1 = Employee('John','Son',50000) emp_2 = Employee('Jane','Son',80000) print(Employee.no_emps) print (emp_1.fullname()) print (emp_1.email) print (emp_1.pay) print (emp_2.pay) emp_1.apply_raise() emp_2.apply_raise() print (emp_1.pay) print (emp_2.pay)
Next, we would be looking at distinguishing regular, static and instance methods in python. Please ask as much questions you can, so we can all learn together. Also leave your contribution on the comment box to improve the piece for all. Like and share.