Abstract Base Classes
Some classes represent an incomplete idea on purpose. A generic "Shape" doesn't have a well-defined area — only a specific shape like a circle or a square does. Python's abc module lets you express that formally: mark a class as abstract, list the methods every concrete subclass must implement, and Python will refuse to create an instance of the class (or of any subclass that skips a required method) until those methods actually exist.
This buys you two things. First, it stops accidental instantiation of a class that was only ever meant to be a template. Second, it catches a missing implementation immediately, as soon as someone tries to use the incomplete subclass, rather than later when some unrelated piece of code calls a method that was never written.
ABC and @abstractmethod
To build an abstract base class, inherit from ABC (from the abc module) and decorate any required method with @abstractmethod. The method's body is never actually run for the abstract version — a pass statement or a docstring is enough, since its only purpose is to declare that subclasses must provide their own implementation.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
"""Every concrete shape must implement this."""
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * self.radius ** 2
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
circle = Circle(3)
square = Square(4)
print(circle.area())
print(square.area())28.27431 16
Both Circle and Square implement area() with logic appropriate to their own shape, and calling code doesn't need to know or care which concrete class it's holding.
Trying to Instantiate the Abstract Class Directly
Shape itself can never be instantiated, because it leaves area() unimplemented. Python enforces this at the moment you try to create an instance.
shape = Shape()
TypeError: Can't instantiate abstract class Shape with abstract method area
A Subclass That Forgets to Implement the Method
Suppose a new subclass is defined but never gets around to implementing area(). Defining the class itself succeeds — Python doesn't check anything at definition time. The error only appears the moment you try to instantiate that incomplete subclass.
class Triangle(Shape):
def __init__(self, base, height):
self.base = base
self.height = height
# area() was never written
t = Triangle(3, 4)TypeError: Can't instantiate abstract class Triangle with abstract method area
Why Bother, Instead of Just Documenting the Requirement?
Prevents instantiating a class that represents an incomplete concept, like a generic Shape with no defined area.
Forces every subclass to implement the required methods, turning a "please remember to implement this" comment into something Python actually enforces.
Fails fast: a missing implementation surfaces as soon as the incomplete class is instantiated, not later when unrelated code eventually calls the missing method and hits an
AttributeErrordeep in some other part of the program.