patternpythonModeratepending
Python abstract base classes and protocols comparison
Viewed 0 times
abcprotocolabstractstructural typingduck typinginterface
Problem
Need to define interfaces in Python: when to use ABC (nominal typing) vs Protocol (structural typing).
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 (must explicitly inherit)
class Serializable(ABC):
@abstractmethod
def serialize(self) -> dict:
...
@abstractmethod
def deserialize(cls, data: dict) -> 'Serializable':
...
class User(Serializable): # Must inherit!
def serialize(self) -> dict:
return {'name': self.name}
@classmethod
def deserialize(cls, data):
return cls(data['name'])
# Protocol: Structural typing (duck typing with type checking)
class Renderable(Protocol):
def render(self) -> str: ...
# No inheritance needed! Just implement the method.
class Button:
def render(self) -> str:
return '<button>Click</button>'
def display(item: Renderable) -> None:
print(item.render()) # Works! Button matches Renderable structurally
display(Button()) # Type-checks correctly
# Runtime checking with Protocol
@runtime_checkable
class Closeable(Protocol):
def close(self) -> None: ...
import io
f = io.StringIO()
isinstance(f, Closeable) # True! StringIO has .close()When to use ABC:
- Want to enforce inheritance hierarchy
- Need shared implementation (mixin methods)
- Framework/library that requires registration
When to use Protocol:
- Want duck typing with type safety
- Third-party classes that can't inherit your ABC
- Defining interfaces for dependency injection
- Most cases in modern Python
Why
Protocols bring static duck typing to Python - you get type safety without forcing classes into an inheritance hierarchy.
Context
Python interface and abstraction design
Revisions (0)
No revisions yet.