Explain Codes LogoExplain Codes Logo

Why use Abstract Base Classes in Python?

python
abstract-classes
method-signatures
type-hinting
Nikita BarsukovbyNikita Barsukov·Aug 29, 2024
TLDR

Abstract Base Classes (ABCs) in Python provide a scaffold for other classes, enforcing a protocol: the subclasses must implement all defined abstract methods. ABCs restrict creation of classes without implementing methods crucial for the object consistency, enhancing reliability and robustness of your codebase.

Below is what using an ABC roughly looks like:

from abc import ABC, abstractmethod class Shape(ABC): @abstractmethod def area(self): """If you are a shape, you better know how to calculate your area!""" pass class Circle(Shape): def area(self): # Fun fact: Pi is round, just like a circle! return 3.14 * self.radius ** 2 # Attempting to instantiate Shape is like trying to catch a ghost. # Circle is totally okay because it knows its area.

Recap:

  • ABCs make sure everyone follows the rules.
  • @abstractmethod marks the methods that cannot be ignored.

Duck-typing and abstract classes

In Python, if it walks like a duck and it quacks like a duck, it's a duck! But with ABCs, you make sure it can actually quack and walk, keeping Python's dynamic flexibility, but adding a security layer against ill-defined duck-like creatures. You define a semantic contract that enforces correct method signatures and semantics, increasing the predictability of your software.

ABCs to prevent AttributeErrors

Implementing abstract methods from an ABC assures that subclass methods won't just kick the can to the superclass method. This prevents wasting time debugging AttributeError. Think about ABCs as method contracts that align developer intent with code functionality.

Type hinting with ABCs

With the rise of type hinting, ABCs become even stronger. You can enforce your type hints, making your intended interfaces a reality and documenting your code without writing volumes of docs.

Specifying need-to-implement interfaces

Using ABCs, everyone knows what is required when dealing with subclassing. This way, any developer can follow along based on those ABCs and produce reliable classes.

Customizing Python built-in behavior

Python ABCs allow developers to customize isinstance() and issubclass() behavior, preserving the type hierarchy's integrity when custom objects come into play.

A note on practical usage

Writing your own ABC is not needed every other day. More often than not, the need makes itself clear through refactoring existing code and recognizing patterns.

Avoid defining ABCs with both __subclasshook__ and non-abstract methods together, as this can confuse users.

Leveraging a sense of agreement

ABCs are akin to a handshake in code: a shared understanding between developers that by following certain rules, they can anticipate the ways in which code will behave.

A familiar concept for Java developers

For developers who come from Java, ABCs in Python may feel familiar and straightforward. Despite being used differently, they provide organizational benefits similar to Java interfaces.

When ABCs come to the rescue

ABCs help in certain scenarios:

  • When you have a generic interface across different subclass implementations.
  • In frameworks, where users plug their own components into a standardized architecture.
  • For larger codebases, where ABCs can provide consistency and defend against runtime exceptions due to missing method attributes.

Tread carefully with ABCs

Like with any tool, improper usage of ABCs can cause problems:

  • Overhead: ABCs add complexity in code and might be overkill for simple projects.
  • Misuse: Incorrect use of ABCs can confuse developers, leading to unclear intentions or overly rigid hierarchy.
  • Refactoring challenges: Any change in the interface could ripple across all subclasses necessitating massive updates, potentially causing errors.

Best practices with ABCs

Keep in mind these practices for working with ABCs:

  • Emphasize method signatures and their semantic meanings.
  • Use ABCs to enforce that subclasses implement host-specific methods.
  • Apply abc.ABCMeta and @abstractmethod to declare abstract methods and properties.