1. Class anatomy: the __init__ constructor
Welcome back! In the previous video, we learned how to define methods and attributes in classes.
2. Methods and attributes
Remember, methods are functions within a class with a special first argument self, and that attributes are created by assignment and referred to using the self variable within methods.
In the exercises, you created an Employee class, and for each new attribute, you defined a new method, and then called those methods one after another. This could get unsustainable if your class contains a lot of data.
3. Constructor
A better strategy would be to add data to the object when creating it, like we do when creating a list or DataFrame.
Python allows us to do this by adding a special method to our class called the constructor. The constructor is automatically called every time an object is created. The method has to be called underscore underscore init underscore underscore - the exact name and double underscores are essential for Python to recognize it.
Here, we define the init method for the Customer class. The method takes on one argument, name, in addition to the self argument that should be there for any method. In the body of the method, we create the name attribute using self.attribute syntax, assigning its value to the name parameter, and print a message.
4. Constructor
Now we can pass the customer name in parentheses when creating a customer object, resulting in the init method being automatically called and the name attribute assigned.
5. The right place to define attributes
So, there are two ways to define attributes: we can define an attribute in any method in a class; and then calling the method will add the attribute to the object. Alternatively, we can define them all together in the constructor.
Where possible, we should avoid defining attributes outside the constructor. Our class definition can be hundreds lines of code long, and the person reading it would have to comb through all of them to find all the attributes.
Additionally, defining all attributes in the constructor ensures that all of them are created when the object is created, so we don't have to worry about trying to access an attribute that doesn't exist yet.
All this results in more organized, readable, and maintainable code.
6. Add arguments
We can add another parameter, account balance, to the init method, and create another attribute, also called balance, that will be initialized during object creation.
7. Add parameters
We can now create a customer object by calling Customer with two parameters in parentheses.
8. Default arguments
The init constructor is also a good place to set the default values for attributes.
For example, here we set the default value of the balance argument to zero.
9. Default arguments
When we create a Customer object without specifying the value of the balance, the attribute is created anyway, and is initialized to the default value zero.
10. Best practices
While we're on the subject of best practices, let's quickly go over a few more conventions that will make our code more user-friendly.
11. Best practices
To name our classes, use camel case, which means that if our class name contains several words, they should be written without underscores and each word should start with a capital letter. For methods and attributes, it's the opposite - words should be separated by underscores and all lowercase.
12. Best practices
The name "self" is a convention. We could use any word for the first variable of a method, it will always be treated as the object reference regardless. However, for consistency, which makes our code easier to understand, we should always use "self".
13. Best practices
Finally, classes allow for docstrings, allowing us to display useful information about our class and objects created from it. Like with custom functions, a docstring for a class must be placed immediately after the line declaring the class.
We should use docstrings to make developer's lives easier.
14. Let's practice!
Now, let's practice creating constructors!