Python is a dynamic and interpreted language. The result is that we do not know the errors in the code unless we run them. This is not the case with languages which are more static and compiled.
Say, you are writing a new banking API. The business case requirement is quite mission critical and so, the library needs to be future-proof. You want the future developers, who are going to use the API, to be implementing the functionality in a specific way.
Let’s say, you have your Banking class which will implement some methods. While creating a class, you are kind of making a promise that this class will implement some methods. To keep things simple, we will only take the case of one method
Similarly, you have started writing implementations for various banks.
class BankingBank1(object): ...
class BankingBank2(object): ...
Now, you see a pattern in them. Being a firm believer in the DRY (Don’t Repeat Yourself) pattern, you will probably move the similar methods to a base class and the child class will implement specific functionality.
But, the subclasses may not be implementing some necessary functionality. You put that on the TODO list and go on a vacation for some days. Once back, you see code like this.
You are appalled. There are multiple if statements checking the type of the object and then deciding the course of action based on that. Classic LBYL. You make a mental note about educating everyone in the team why LBYL is bad. A champ of the EAFP principle, you refactor the code.
But you are not happy. The issue with this kind of implementation is that the object gets created and error is not raised till the method is called. This might be a problem if some other methods are getting executed before this method is called. This is a problem in interpreted languages like Python. In compiled languages, this kind of error would get raised at the compilation phase itself.
Things should fail fast and if possible at the instantiation level itself, isn’t it? There goes your mentor, the programming friend who always helps out and lo, he tells you that it can be achieved using the abstract base class and the abstract method decorator. He sketches out the rough basics and you start writing the code.
You test if it works or not. Sure enough, TypeError gets raised while trying to create the object itself.
You can now rest assure that no functionality will get implemented and the object will fail in the instantiation phase only.
You know a new pattern now and want to know some more before calling it a day. You go through various resources:
- Collections.abc has some common patterns that can be implemented. You can create custom types using these patterns.
- Some good design patterns are implemented using abstract method.
Stackoverflow. “Why use abstract base classes in Python”
Guido van Rossum. 2007. PEP 3119.
Dan Bader. Abstract Base Classes in Python
Hope you liked this!
To get regular updates on more content, learning material and general rants you can follow me on Twitter.