Protocol enables duck typing with type safety — no inheritance required.
1from typing import Protocol, runtime_checkable23# Define protocol4@runtime_checkable5class Drawable(Protocol):6 def draw(self) -> str: ...78class Circle:9 def draw(self) -> str:10 return "Drawing circle"1112class Square:13 def draw(self) -> str:14 return "Drawing square"1516class Line:17 def draw(self) -> str:18 return "Drawing line"1920# Any object with draw() works!21def render(shape: Drawable) -> str:22 return shape.draw()2324render(Circle()) # OK — has draw()25render(Square()) # OK — has draw()26render(Line()) # OK — has draw()2728# Runtime check29print(isinstance(Circle(), Drawable)) # True3031# Protocol with properties32@runtime_checkable33class Closeable(Protocol):34 def close(self) -> None: ...35 @property36 def is_closed(self) -> bool: ...
Benefits: