Abstract Base Classes in Python: Fundamentals for Data Scientists
By: Erdem Isbilen
Tags: Python, Data Science, Oop, Abstract Base Classes, Programming

Abstract Base Classes in Python: Fundamentals for Data Scientists

Understand the basics with a concrete example!

Photo by Joshua Aragon on Unsplash

In Python, abstract base classes provide a blueprint for concrete classes. They don’t contain implementation. Instead, they provide an interface and make sure that derived concrete classes are properly implemented.

Abstract base classes cannot be instantiated. Instead, they are inherited and extended by the concrete subclasses.

Subclasses derived from a specific abstract base class must implement the methods and properties provided in that abstract base class. Otherwise, an error is raised during the object instantiation.

Let’s write a Python3 code that contains simple examples of implementing abstract base classes:

from abc import ABCMeta, abstractmethod class AbstactClassCSV(metaclass = ABCMeta):



def __init__(self, path, file_name):

self._path = path

self._file_name = file_name @property

@abstractmethod

def path(self):

pass @path.setter

@abstractmethod

def path(self,value):

pass @property

@abstractmethod

def file_name(self):

pass @file_name.setter

@abstractmethod

def file_name(self,value):

pass @abstractmethod

def display_summary(self):

pass

Photo by John Duncan on Unsplash

Defining an Abstract Base Class

Python provides an abc module for the abstract base class definition. We need to import ABCMeta metaclass and assign it to the abstract class we want to define.

from abc import ABCMeta, abstractmethod class AbstactClassCSV(metaclass = ABCMeta):

.....

.....

Inside the abstract base class, we force the subclasses to implement the path and file_name properties with the use of @abstractmethod decorator. Note that the properties are not implemented and empty as abstract classes are used only for defining the interface.

@property

@abstractmethod

def path(self):

pass @path.setter

@abstractmethod

def path(self,value):

pass @property

@abstractmethod

def file_name(self):

pass @file_name.setter

@abstractmethod

def file_name(self,value):

pass

Again, with @abstractmethod decorator, we can define an abstract method and force the subclasses to implement the display_summary(self) method.

@abstractmethod

def display_summary(self):

pass

At this point, if we try to instantiate an object of AbstactClassCSV abstract class, we get an error.

abc_instantiation = AbstactClassCSV("/Users/erdemisbilen/Lessons/", "data_by_genres.csv") Output: Traceback (most recent call last):

File "ABCExample.py", line 119, in <module>

abc_instantiation = AbstactClassCSV("/Users/erdemisbilen/Lessons/", "data_by_genres.csv")

TypeError: Can't instantiate abstract class AbstactClassCSV with abstract methods display_summary, file_name, path

Photo by Benoit Gauzere on Unsplash

Creating a Concrete Subclass Derived From an Abstract Base Class

Now that we have our abstract base class (AbstactClassCSV) is defined, we can create our subclass by inheriting.

Below, I created CSVGetInfo concrete class, by inheriting from AbstactClassCSV abstract class. Therefore, I must strictly follow the interface provided by the abstract class and implement all dictated methods and properties properly in my concrete subclass.

class CSVGetInfo(AbstactClassCSV): """ This class displays the summary of the tabular data contained in a CSV file """ @property

def path(self):

""" The docstring for the path property """

print("Getting value of path")

return self._path @path.setter

def path(self,value):

if '/' in value:

self._path = value

print("Setting value of path to {}".format(value))

else:

print("Error: {} is not a valid path string".format(value)) data_by_genres = CSVGetInfo("/Users/erdemisbilen/Lessons/", "data_by_genres.csv") Output: Traceback (most recent call last):

File "ABCExample.py", line 103, in <module>

data_by_genres = CSVGetInfo("/Users/erdemisbilen/Lessons/", "data_by_genres.csv")

TypeError: Can't instantiate abstract class CSVGetInfo with abstract methods display_summary, file_name

As to demonstrate the case, I only defined the path property and leave the file_name property and display_summary method not implemented.

If I try to instantiate an object of CSVGetInfo in such state, the above error is raised.

That is how abstract classes prevent improper subclass definition.

class CSVGetInfo(AbstactClassCSV):

""" This class displays the summary of the tabular data contained

in a CSV file """ @property

def path(self):

""" The docstring for the path property """

print("Getting value of path")

return self._path @path.setter

def path(self,value):

if '/' in value:

self._path = value

print("Setting value of path to {}".format(value))

else:

print("Error: {} is not a valid path string".format(value)) @property

def file_name(self):

""" The docstring for the file_name property """

print("Getting value of file_name")

return self._file_name @file_name.setter

def file_name(self,value):

if '.' in value:

self._file_name = value

print("Setting value of file_name to {}".format(value))

else:

print("Error: {} is not a valid file name".format(value)) def display_summary(self):

data = pd.read_csv(self._path + self._file_name)

print(self._file_name)

print(data.info())

As we defined all required properties and the methods dictated by abstract class above, now we can instantiate and use the objects of derived subclass CSVGetInfo.

Photo by Vincent van Zalinge on Unsplash

Key Takeaways

Abstract base classes separate the interface from the implementation.

They make sure that derived classes implement methods and properties dictated in the abstract base class.

Abstract base classes separate the interface from the implementation. They define generic methods and properties that must be used in subclasses. Implementation is handled by the concrete subclasses where we can create objects that can handle tasks.

They help to avoid bugs and make the class hierarchies easier to maintain by providing a strict recipe to follow for creating subclasses.

Conclusion

In this post, I explained the basics of abstract base classes in Python.

The code in this post is available in my GitHub repository.

I hope you found this post useful.

Thank you for reading!