Instance and class data

1. Instance and class data

Congratulations! Now you know the basics of creating classes. You might be asking: classes are neat, but how exactly do they help me make my code better? In this chapter, you'll learn about

2. Core principles of OOP

namely, Inheritance and Polymorphism, that, together with encapsulation, form the core principles of OOP. But before we get into it,

3. Instance-level data

you need to learn how to distinguish between instance-level data and class level data. Remember the employee class you defined in the previous chapter. It had attributes like name and salary, and we were able to assign specific values to them for each new instance of the class. These were instance attributes. We used self to bind them to a particular instance.

4. Class-level data

But what if you needed to store some data that is shared among all the instances of a class? For example, if you wanted to introduce a minimal salary across the entire organization. That data should not differ among object instances. Then, you can define an attribute directly in the class body. This will create a class attribute, that will serve as a "global variable" within a class. For example,

5. Class-level data

we can define min_salary, and set it to 30000. We can use this attribute inside the class like we would use any global variable, only prepended by the class name: for example, here we check if the value of salary attribute is greater than MIN_SALARY in the init method. Note that we do not use self to define the attribute, and we use the class name instead of self when referring to the attribute.

6. Class-level data

This min_salary variable will be shared among all the instances of the employee class. We can access it like any other attribute from an object instance, and the value will be the same across instances. Here we print the MIN_SALARY class attribute from two employee objects.

7. Why use class attributes?

So, the main use case for class attributes is global constants that are related to class, for example min/max values for attributes -- like the min_salary example -- or commonly used values: for example,if you were defining a Circle class, you could store pi as a class attribute.

8. Class methods

What about methods? Regular methods are already shared between instances: the same code gets executed for every instance. The only difference is the data that is fed into it. It is possible to define methods bound to class rather than an instance, but they have a narrow application scope, because these methods will not be able to use any instance-level data. To define a class method, you start with a classmethod decorator, followed by a method definition. The only difference is that now the first argument is not self, but cls, referring to the class, just like the self argument was a reference to a particular instance. Then you write it as any other function, keeping in mind that you can't refer to any instance attributes in that method. To call a class method, we use class-dot-method syntax, rather than object-dot-method syntax.

9. Alternative constructors

So why would we ever need class methods at all? The main use case is alternative constructors. A class can only have one init method, but there might be multiple ways to initialize an object. For example, we might want to create an Employee object from data stored in a file. We can't use a method, because it would require an instance, and there isn't one yet! Here we introduce a class method from_file that accepts a file name, reads the first line from the file that presumably contains the name of the employee, and returns an object instance. In the return statement, we use the cls variable -- remember that now cls refers to the class, so this will call the init constructor, just like using Employee with parentheses would when used outside the class definition.

10. Alternative constructors

Then we can call the method from_file by using class-dot-method syntax, which will create an employee object without explicitly calling the constructor.

11. Let's practice!

That was a lot! Now head over to the exercises to practice.