Dunder Method - Special Methods
What is dunder method
- A method with 2 underscores around it like_this is called as "double underscore method" i.e. dunder method, which is not an official term.
- Officially these are called as "special methods" or as "magic method" in some cases
- They act as "hook", allowing us to customize the behaviour of built in Python functions
Definition in classes
- This depends on whether we are inheriting a class or defining our own functions inside a class
- init - initializer method
-
repr - this is developer focused string representation
-
eq - this method can give our objects a nice sense of equality
- iter - this method if our objects support unpacking
Calling dunder methods for Objects
- We should implement dunder methods on our objects but should not call dunder methods on other objects
- They should be implemented by us and called by Python
-
Instead of calling dunder methods it is better to use higher level operations that are powered by those dunder methods """ from datetime import date from pathlib import Path path = Path.cwd() today = date.today() """
-
If we want to convert these objects to strings, we could call the str method on these objects: """ path_string = path.str() date_string = today.str() path_string '/home/trey' date_string '2024-01-17' """
-
But we're not supposed to do that! We're meant to pass those objects to the built-in str function: """ path_string = str(path) date_string = str(today) """ The same applies for every other dunder method.
-
We should use the len function to get an object's length, not the len method: """ my_collection.len() # no len(my_collection) # yes """
Why not call the dunder method
- But there's another reason you shouldn't call dunder methods: there's not a one-to-one relationship between dunder methods and the features they empower. Sometimes calling dunder methods won't be nearly as straightforward as using a corresponding higher-level Python feature.
- For example, if we want to divide one number by another, we could use the / operator or we could use the truediv method: """ n = 10 m = 2 n / m 5.0 n.truediv(m) 5.0 """
- But while the / operator will always give us the expected answer, the truediv will not: """ m = 2.5 n / m 4.0 n.truediv(m) NotImplemented """
- Integers don't know how to interact with floating point numbers, so when using the / operator between an integer and a floating point number, Python needs to ask the floating point number to divide the integer by itself. It does this by using its rtruediv method: """ m.rtruediv(n) 4.0 """
Sometimes we need to call dunder methods
- In case if we are implementing custom methods inside the class then we will have to call the dunder method in that case
Avoid calling dunder method but do define them
- We should avoid calling them because -
- There's not always a one-to-one relationship between high-level operations and individual dunder methods
- Dunder method calls signals that something low-level is happening
-
There's usually a higher-level way to do the same thing that looks friendlier
-
If we want to achieve something at a low level then yes we should call them otherwise for high level programming we should avoid using them.