Python Abstraction
In this page:
from abc import ABC, abstractmethod
class AbstractClass(ABC):
@abstractmethod
def method_name(self):
pass
What is Abstraction?
Abstraction means designing your class's public interface to expose only what a caller actually needs -- a Car class might expose .start() while hiding the ignition sequence entirely -- so users of the class can't accidentally depend on implementation details that might change later.
Example: What is Abstraction?
class Car:
def start(self):
print("Car started") # ignition sequence hidden
Car().start()
The abc Module
The abc module's ABC base class and @abstractmethod decorator let you define a class that can't be instantiated directly and forces any subclass to implement specific methods -- trying to instantiate a subclass that skips an abstract method raises a TypeError immediately.
Example: The abc Module
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
try:
Shape() # can't instantiate an abstract class directly
except TypeError as e:
print(e)
Abstract Properties
Combining @property with @abstractmethod lets you require subclasses to implement a specific attribute-like value (rather than a regular method) -- useful when every subclass must define something like .area, but each computes it differently.
Example: Abstract Properties
from abc import ABC, abstractmethod
class Shape(ABC):
@property
@abstractmethod
def area(self): # requires subclasses to implement area as a property
pass
class Square(Shape):
def __init__(self, side):
self.side = side
@property
def area(self):
return self.side ** 2
print(Square(3).area)
Multiple Abstract Methods
An abstract class can declare as many abstract methods as its interface needs, and Python won't let a subclass be instantiated until every single one of them has a concrete implementation -- partial implementations still raise TypeError on instantiation.
Example: Multiple Abstract Methods
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
class Square(Shape): # must implement both abstract methods to be instantiable
def __init__(self, side):
self.side = side
def area(self):
return self.side ** 2
def perimeter(self):
return self.side * 4
print(Square(3).area(), Square(3).perimeter())
Benefits of Abstraction
Because code that depends on an abstract interface doesn't know or care which concrete subclass it's actually working with, you can swap one implementation for another (a MockDatabase instead of a RealDatabase in tests, for instance) without touching the code that uses it.
Example: Benefits of Abstraction
class RealDatabase:
def get_user(self):
return "real user"
class MockDatabase:
def get_user(self):
return "mock user"
def show_user(db):
print(db.get_user()) # doesn't care which concrete class db is
show_user(MockDatabase()) # swap in a different implementation with no change above
- Instantiating an abstract class directly, as in
Shape(), which raisesTypeErrorbecause abstract methods are not implemented. - Forgetting to use
ABCor@abstractmethod, so the class does not enforce anything and missing methods go unnoticed. - Forgetting to override every abstract method in the subclass, which leaves the subclass abstract too, so it still cannot be instantiated.
Chapter Quiz — Complete all 11 topics to unlock
0/11 topics done
Complete these topics first: