patternpythonModeratepending
Python ABC and Protocol - Abstract Classes vs Structural Typing
Viewed 0 times
ABCProtocolabstract classstructural typinginterfaceduck typing
Problem
Need to define interfaces in Python but unsure whether to use ABC (abstract base classes) or Protocol (structural typing), and when each is appropriate.
Solution
ABC vs Protocol comparison:
When to use ABC:
When to use Protocol:
from abc import ABC, abstractmethod
from typing import Protocol, runtime_checkable
# === ABC: nominal typing (explicit inheritance) ===
class Serializable(ABC):
@abstractmethod
def to_dict(self) -> dict:
...
@abstractmethod
def from_dict(cls, data: dict) -> 'Serializable':
...
# Can have concrete methods too
def to_json(self) -> str:
return json.dumps(self.to_dict())
# MUST explicitly inherit
class User(Serializable):
def to_dict(self) -> dict:
return {'name': self.name}
@classmethod
def from_dict(cls, data):
return cls(name=data['name'])
# === Protocol: structural typing (duck typing for type checkers) ===
class Renderable(Protocol):
def render(self) -> str: ...
# No inheritance needed! Just implement the method
class HTMLWidget:
def render(self) -> str:
return '<div>widget</div>'
def display(item: Renderable) -> None:
print(item.render())
display(HTMLWidget()) # Works! HTMLWidget matches Renderable structurally
# Runtime checking (optional)
@runtime_checkable
class Closeable(Protocol):
def close(self) -> None: ...
import io
isinstance(io.StringIO(), Closeable) # True! Has .close() methodWhen to use ABC:
- Shared implementation (concrete methods in the base)
- Registration pattern (register virtual subclasses)
- Runtime isinstance checks (always works)
- Framework extension points
When to use Protocol:
- Third-party code compatibility (can't modify their classes)
- Duck typing with type safety
- Lightweight interfaces (no inheritance required)
- When you want structural, not nominal, subtyping
Why
ABC enforces implementation through inheritance (nominal). Protocol works like Go interfaces - if it has the right methods, it satisfies the type (structural). Protocol is more Pythonic and flexible.
Gotchas
- Protocol runtime_checkable only checks method existence, not signatures
- ABC can't be used with classes you don't control (third-party code)
Context
Defining interfaces and contracts in Python
Revisions (0)
No revisions yet.