Implementing dunder methods for classes is a good form of Polymorphism. If you have ever created a class in Python and used the init function, then you have already been using dunder methods.
Before we continue it will be important to have the following:
A basic understanding of Object Oriented Programming using Python.
Experience working with classes in Python.
Familiarity with built-in functions such as len, get, set, etc.
Consider a case where we have the following class:
The print statement would print something like <__main__.point object at 0x7fb992998d00>
. But, we might want the print statement to display something in the format (4,10)
. We can achieve this by overriding the __str__
method of our class.
We could also override other methods such as the len, +, []
etc. We will create a new class and override many of the built-in functions in this article.
This class will be used to save a list of software and their versions. names
is a list to store the names of the software and versions
is a dictionary where the key is the software name and the value is the version number. By default, all softwares start with a version of 1.
Before moving on, please ensure that your indentation is correct. The methods that will be discussed below are methods belonging to the class we created and must be indented appropriately.
6.1. init
This is a method you must have already used if you have worked with classes. The init
method is used to create an instance of the class.
The init
method defined above accepts a list of names as parameters and stores it in the class’ names
list. Additionally, it also populates the versions
dictionary. We have also put a check on the names
list.
If the list is empty, an exception is raised. Below is how we would use the init
method.
The first statement would work fine but the second line would raise an exception since an empty list was passed in as a parameter.
6.2. str
The str
method is useful when we want to use instances of our class in a print statement. As discussed earlier, it usually returns a memory object. But we can override the str
method to meet our requirements.
The above str
method returns the software and their versions. Ensure that the function returns a string. Below is how we would call the method.
6.3. setitem
When assigning values in a dictionary, the setitem
method is invoked.
We can give instances of our class a similar feature with the help of the setitem
method.
The method above is going to update the version number of the software. If the software is not found, it will raise an error.
In the 3rd line, we use the built-in setitem
method of a dictionary.
We can invoke the setitem
method in the following way:
The first line would update the version of software S1 to 2. But the second line would raise an exception since software 2 doesn’t exist.
6.4. getitem
The getitem
method is like the setitem
method, the major difference being that the getitem
method is called when we use the []
operator of a dictionary.
Instances of our class can also be given a similar feature.
The above method essentially returns the version of the software. If the software is not found, it raises an exception. To invoke the getitem
method, we can write the following line of code.
The first line would print the version of S1. But, the second line would raise an Exception since 1 doesn’t exist.
6.5. delitem
The delitem
is like the setitem
and getitem
method. To avoid repetition, we will move on to the implementation and use case.
The delitem
method deletes the software from the dictionary as well as the list.
It can be used as follows.
6.6. len
In a dictionary, the len
method returns the number of elements in a list or the number of key-value pairs in a dictionary.
We can define a len
method for our class as well.
The len
method for our class returns the number of softwares. As you might have noticed, we are using the built-in len
method of a list to return the number of software.
The len
method of our class can be used in the following way.
6.7. contains
The contains
method is used when using the in
operator. The return value has to be a boolean.
The method checks if the name is found in the dictionary. We will be using the dictionary’s built-in contains
method for that.
The code above prints the statement inside the if blocks since software S2 is present inside the versions
dictionary.
6.8. Complete code
Before looking at some more dunder methods, let’s create a new class.
We have created a class point which is basically a 2D point. The class has an init
method and a str
method. We have also created a couple of instances of the class.
7.1. add
The add
method is called when using the +
operator. We can define a custom add
method for our class.
p1 + p2
is equal to p1._add__(p2)
The above method adds the x and y coordinates of the first instance of point
and the second instance of point
. It will create a new instance of point
and then return it.
The line of code above invokes the add
method.
7.2. iadd
The iadd
method is like the add
method. It is invoked when using the +=
operator
The method above just updates an instance’s coordinates by adding the coordinates of p2
. Make sure you are returning self
, otherwise it will return None and won’t work as expected.
The above method invokes the iadd
method.
7.3. Other operators
__sub__(self,p2)
( - )
__isub__(self,p2)
( -= )
__mul__(self,p2)
( * )
__imul__(self,p2)
( *= )
__truediv__(self,p2)
( \ )
__itruediv__(self,p2)
( \= )
__floordiv__(self,p2)
( \\ )
__ifloordiv__(self,p2)
( \= )
7.4. call
When invoking a function like func()
, we are invoking the call
method.
If we put in place a call
method for our class, we can do the following:
Below is an example call method:
7.5. Complete code