pythonadvanced

Protocol Classes for Structural Typing

Define interfaces with Protocol for duck-typing that works with static type checkers.

python
from typing import Protocol, runtime_checkable
from dataclasses import dataclass

@runtime_checkable
class Drawable(Protocol):
    x: float
    y: float
    def draw(self) -> str: ...
    def area(self) -> float: ...

@dataclass
class Circle:
    x: float
    y: float
    radius: float

    def draw(self) -> str:
        return f"Circle at ({self.x}, {self.y}) r={self.radius}"

    def area(self) -> float:
        import math
        return math.pi * self.radius ** 2

@dataclass
class Square:
    x: float
    y: float
    side: float

    def draw(self) -> str:
        return f"Square at ({self.x}, {self.y}) s={self.side}"

    def area(self) -> float:
        return self.side ** 2

def render(shapes: list[Drawable]) -> None:
    for shape in shapes:
        print(f"{shape.draw()} area: {shape.area():.2f}")

c = Circle(0, 0, 5)
print(isinstance(c, Drawable))  # True
render([Circle(0, 0, 5), Square(1, 1, 3)])

Use Cases

  • dependency injection
  • plugin systems
  • testable interfaces

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.