Phase 14 of 25 · Topic 14.3

Protocol Classes (PEP 544) & Structural Subtyping

1Concept

`typing.Protocol` enables static duck typing (structural subtyping). A class satisfies a Protocol if it implements the required methods and attributes, without needing to explicitly inherit from the Protocol class.

2Architecture Diagram

Protocol: class Renderable(Protocol): def render() -> str
Any class with def render() satisfies Renderable automatically (Zero inheritance needed!)

3Code Example

Python 3.12
from typing import Protocol

class Renderable(Protocol):
    def render(self) -> str: ...

class HtmlCard:
    def render(self) -> str:
        return "<div class='card'>Card Content</div>"

class JsonCard:
    def render(self) -> str:
        return '{"type": "card", "content": "Card Content"}'

def display_ui(component: Renderable) -> None:
    print(f"Rendered: {component.render()}")

display_ui(HtmlCard())
display_ui(JsonCard())

4Expected Output

Rendered: <div class='card'>Card Content</div>
Rendered: {"type": "card", "content": "Card Content"}

5Key Takeaways

  • Decorate with `@typing.runtime_checkable` to allow `isinstance(obj, Protocol)` at runtime.
  • Achieves clean interface-based decoupling without rigid class inheritance trees.
  • Python's answer to Go interfaces and TypeScript structural typing.