ABC Module and Abstract Methods

RoadmapsPython

Overview

The `abc` module provides the `ABC` class and `@abstractmethod` decorator to define Abstract Base Classes. These classes cannot be instantiated directly and force child classes to implement specific methods before they can be instantiated. Think of it like a strict contract or a blueprint: a 'Vehicle' blueprint says you must build an 'engine', but you can't drive the blueprint itself. In Python, if a child class inherits from `ABC` but forgets to override an `@abstractmethod`, Python raises a `TypeError` at instantiation time, not when the method is called. A subclass cannot be instantiated until it implements EVERY `@abstractmethod` — an ABC is an enforced interface contract. When combining `@abstractmethod` with decorators like `@property` or `@classmethod`, it must be the innermost decorator. Placing it on the outside breaks the enforcement: class Broken(ABC): @abstractmethod @property def value(self): pass In this broken example, Python fails to recognize `value` as an abstract method, allowing subclasses to be instantiated without implementing it.

It prevents developers from accidentally creating incomplete subclasses, enforcing a strict API contract across a codebase and catching bugs early.

Where used: Django BaseCommand, Collections.abc

Why learn this

Code walkthrough

from abc import ABC, abstractmethod

class Worker(ABC):
    @abstractmethod
    def work(self):
        pass

class LazyWorker(Worker):
    pass

try:
    w = LazyWorker()
except TypeError as e:
    print(e)

Focus: `w = LazyWorker()` # Fails because `LazyWorker` didn't implement `work()`

Aha moment

from abc import abstractmethod

class FakeAbstract:
    @abstractmethod
    def do_something(self):
        pass

obj = FakeAbstract()
print('Created successfully!')

Prediction: What happens when we instantiate `FakeAbstract`?

Common guess: It raises a `TypeError` because of the abstract method.

It prints `'Created successfully!'`. The `@abstractmethod` decorator only enforces instantiation rules if the class also inherits from `ABC`. Without `ABC`, the decorator does nothing.

Common mistakes

Recall questions

Understanding checks

What happens when this code is executed?

It prints `'Woof!'`.

The `Animal` class does not inherit from `ABC`, so the `@abstractmethod` decorator has no enforcing effect. The `Dog` class can be instantiated normally.

What happens when this code is executed?

A `TypeError` is raised at `d = Dog()`.

Because `Animal` inherits from `ABC` and `speak` is decorated with `@abstractmethod`, `Dog` must implement `speak` before it can be instantiated.

What happens when this code is executed?

It prints `'Success'`.

Because `@abstractmethod` is placed outside of `@classmethod`, it is ignored. `Child` can be instantiated without implementing `my_method`. To enforce the contract, `@abstractmethod` must be the innermost decorator.

Practice tasks

Enforce a Contract

Currently, `PaymentGateway` is just a regular class, and `StripeGateway` inherits from it but doesn't implement `process_payment`. Modify `PaymentGateway` to inherit from `ABC` and decorate `process_payment` with `@abstractmethod`. Then implement `process_payment` in `StripeGateway` so that it returns a string.

Challenge

Implement an Exporter Interface

Create an abstract base class `DataExporter` with an abstract method `export(self, data)`. Create a subclass `JSONExporter` that implements `export` by returning the data wrapped in a string like `'JSON: [data]'`. Create another subclass `CSVExporter` that forgets to implement `export`. Attempting to instantiate `CSVExporter` should fail with a `TypeError`.

Continue learning

Previous: Class Creation and Instantiation

Previous: Single inheritance and super()

Previous: Method Overriding

Next: Structural Subtyping with Protocols

Return to Python Roadmap