Polymorphism & Abstraction
Protocols (PEP 544)
Structural subtyping for static duck typing
Interview: Modern Python typing — tests understanding of structural vs nominal typing and Protocol best practices
Protocols (PEP 544, Python 3.8+) enable structural subtyping — a way to define interfaces based on method signatures rather than inheritance. Any class with matching methods satisfies a Protocol, even without explicit inheritance. This brings "static duck typing" to Python: you get duck typing's flexibility with static type checking safety.
Key Features
- No inheritance required — any matching class satisfies the Protocol
- Works with mypy and other type checkers for static analysis
@runtime_checkableenablesisinstance()checks at runtime- Protocols can be composed (multiple inheritance of Protocols)
- Method bodies use
...(ellipsis) as placeholder
Protocol vs ABC
- Protocol: Structural typing, no inheritance needed, opt-in
- ABC: Nominal typing, requires inheritance, enforced at instantiation
- Use Protocol for flexibility and type checking; ABC for enforcement
Interview Tip
Protocols are the modern Python answer to "how do you define interfaces?" — they combine the flexibility of duck typing with the safety of static type checking. This is increasingly important in large codebases.
Use Cases
Type-safe duck typing in large codebases with mypy
Defining API contracts without requiring inheritance
Generic interfaces (Repository[T], Serializer[T])
Testing: mock objects that satisfy Protocols without inheritance
Library APIs: accept any object matching the Protocol, not just subclasses
Common Mistakes
Forgetting @runtime_checkable when using isinstance() with Protocols
Using pass instead of ... (ellipsis) in Protocol method bodies
Not understanding that Protocols are checked structurally, not nominally
Runtime checking only verifies method existence, not signatures
Over-using Protocols for simple cases where ABC or duck typing suffices