Interfaces in Python
Python does not have the traditional interface
keyword as seen in other programming languages. Instead, the language supports ducktyping and multiple inheritance which may satisfy the need for interfaces for some use cases.
However, there are native pythonic methods to create / implement an interface.
Ducktyping
If it quacks like a duck and walks like a duck, Python assumes it’s a duck:
1from dataclasses import dataclass
2
3@dataclass
4class User:
5 id: str
6 name: str
7
8class UserService:
9 def get_user_by_id(self, id: str) -> User:
10 """Retrieve user by ID"""
11 pass
12
13class Database(UserService):
14 def get_user_by_id(self, id: str) -> User:
15 """Retrieves user by ID from an database"""
16 # Implementation goes here
17 pass
18
19class Cache(UserService):
20 def get_user_by_id(self, id: str) -> User:
21 """Retrieves user by ID from cache"""
22 # Implementation goes here
23 pass
Due to the lack of enforcement, this paradigm may not scale well for the implementer’s needs.
Abstract Base Classes
Introduced in Python 2.6, abstract base classes allow for interface creation.
1from abc import ABC, abstractmethod
2from dataclasses import dataclass
3
4@dataclass
5class User:
6 id: str
7 name: str
8
9class UserService(ABC):
10 @abstractmethod
11 def get_user_by_id(self, id: str) -> User:
12 """Retrieve user by ID"""
13 raise NotImplementedError
14
15class Database(UserService):
16 def get_user_by_id(self, id: str) -> User:
17 """Retrieves user by ID from a database"""
18 # Implementation goes here
19 pass
This covers two cases:
- The inheriting class must implement the abstract method
- The implementation cannot instantiate this parent’s method:
super().get_user_by_id(id)