Python Abstract Base Classes: Enforce Interfaces with ABC
Imagine you're an architect handing blueprints to a construction crew. The blueprint says "there must be a front door here" and "the roof goes here." The crew can choose the materials and style, but they must include those parts. If they skip the front door, the building inspector will reject the project.
Abstract Base Classes (ABCs) work the same way in Python. They let you create a blueprint for other classes, forcing them to implement specific methods. If a subclass forgets one, Python raises an error immediately — not later when things break in production.
In this tutorial, you'll learn how to define abstract classes, require methods with @abstractmethod, create abstract properties, and decide when ABCs are the right tool versus Python's flexible duck typing.
What Is an Abstract Class?
A regular class is like a cookie cutter — you stamp it and get an object. An abstract class is different. It's a template that says "every cookie must have these features," but you can't use the template directly to make a cookie.
In technical terms, an abstract class is a class that cannot be instantiated on its own. It exists only to be inherited by other classes, which must fill in the missing pieces.
Why would you want a class you can't create objects from? Because it gives you a contract. Any class that inherits from it is guaranteed to have certain methods. This makes large codebases much more predictable.
The problem above is that you only discover the missing method when the code runs and someone calls area(). In a big project, that could be months later. ABCs catch this immediately.
How Do You Create an Abstract Class with ABC?
Python's abc module gives you two things: the ABC base class and the @abstractmethod decorator. Import them, inherit from ABC, and mark any methods that subclasses must implement.
Python refuses to create a Shape object because it has abstract methods. Now let's create a proper subclass that implements everything.
Notice that describe() is a regular method on the abstract class. It's not abstract, so subclasses inherit it for free. You can mix abstract methods (must override) with concrete methods (shared behavior) in the same class.
Can You Make Abstract Properties?
Sometimes you don't just want subclasses to implement methods — you want them to provide specific properties too. You can combine @property with @abstractmethod to require this.
Abstract properties are useful when every subclass must have a certain attribute, but each subclass computes or stores it differently. The abstract class can use these properties in its own concrete methods, trusting that subclasses will provide them.
When Should You Use ABCs vs Duck Typing?
Python is famous for duck typing: "if it walks like a duck and quacks like a duck, it's a duck." You don't need a formal interface — if an object has the right methods, it works.
So when should you reach for ABCs instead? ABCs shine when you're building a framework or a library that other people will extend. They provide clear documentation about what's required and give immediate feedback when something is missing.
# No enforcement — just hope for the best
class PaymentProcessor:
def charge(self, amount):
raise NotImplementedError
# Forgot charge()? No error until runtimefrom abc import ABC, abstractmethod
class PaymentProcessor(ABC):
@abstractmethod
def charge(self, amount):
pass
# Forgot charge()? Instant TypeErrorYou can also use isinstance() checks with ABCs. When a class inherits from your ABC, isinstance() returns True, making it easy to validate objects at runtime.
What Are Some Real-World ABC Patterns?
ABCs really shine in plugin systems. Imagine you're building a notification service that can send messages through email, SMS, or push notifications. You define an ABC that every notification plugin must follow.
The send_alert function doesn't care which type of notifier it gets — it just knows that any Notifier subclass will have a send() method. This is the power of programming to an interface.
Python's own standard library uses ABCs extensively. The collections.abc module defines abstract classes like Iterable, Mapping, and Sequence. When you create a custom collection, inheriting from these ABCs tells Python (and other developers) exactly what your class supports.
Practice Exercises
Create an abstract class called Animal that inherits from ABC. It should have two abstract methods: speak() and move(). Then create a Dog class that inherits from Animal where speak() returns the string 'Woof!' and move() returns 'Runs on four legs'. Finally, create a dog and print both methods.
What does this code print? Think carefully about which abstract methods are implemented and which are missing.
from abc import ABC, abstractmethod
class Database(ABC):
@abstractmethod
def connect(self):
pass
@abstractmethod
def disconnect(self):
pass
class SQLite(Database):
def connect(self):
return 'Connected'
try:
db = SQLite()
except TypeError as e:
print('Cannot create instance')This code is supposed to define an abstract Logger class and a FileLogger that implements it. But it has bugs! Fix them so the output is:
Logging to file: Server startedCreate an abstract class Employee with an abstract property role and an abstract method salary(). Then create two subclasses:
Engineer where role returns 'Engineer' and salary() returns 95000Manager where role returns 'Manager' and salary() returns 120000Create one of each and print their info in the format: Role: salary
The code below uses NotImplementedError to simulate abstract methods. Refactor it to use ABC and @abstractmethod instead. Keep the same output:
Area: 50
Area: 78.5Remove all NotImplementedError raises and use proper abstract methods.