patternpythonnoneModerate
typing.Protocol for Structural Subtyping in Python
Viewed 0 times
Python 3.8+
Protocolstructural subtypingduck typinginterfacePEP 544
Error Messages
Problem
Using ABC (Abstract Base Classes) for interfaces requires explicit inheritance, breaking duck typing. Third-party classes can't implement your interface without modification.
Solution
Use typing.Protocol for structural subtyping — any class with matching methods satisfies the protocol.
from typing import Protocol, runtime_checkable
@runtime_checkable
class Drawable(Protocol):
def draw(self, canvas: 'Canvas') -> None: ...
def get_bounds(self) -> tuple[float, float, float, float]: ...
# Any class with these methods satisfies Drawable
class Circle: # No inheritance needed!
def draw(self, canvas: 'Canvas') -> None:
canvas.draw_circle(self.x, self.y, self.radius)
def get_bounds(self) -> tuple[float, float, float, float]:
return (self.x - self.radius, self.y - self.radius,
self.x + self.radius, self.y + self.radius)
def render(shape: Drawable) -> None:
shape.draw(canvas)
render(Circle(0, 0, 5)) # OK — Circle is structurally Drawable
# Runtime check (requires @runtime_checkable)
assert isinstance(Circle(0, 0, 5), Drawable) # TrueWhy
Protocol implements PEP 544 structural subtyping. Unlike ABC, it doesn't require explicit registration or inheritance — matching the interface structurally is sufficient.
Gotchas
- @runtime_checkable only checks for the existence of methods, not their signatures.
- Protocol classes should not have implementation — use ABC if you need default implementations.
- Class variables in Protocols must be declared with ClassVar to distinguish from instance attributes.
Revisions (0)
No revisions yet.