Python - Typing Advanced
Overview
Estimated time: 30–45 minutes
Go beyond basics with structural typing (Protocols), precise dict types (TypedDict), generics, and callable signatures.
Learning Objectives
- Define Protocols and use runtime_checkable where useful.
- Use TypedDict for structured dicts; migrate gradually.
- Write generic classes/functions with TypeVar/ParamSpec.
Examples
from typing import Protocol, runtime_checkable, TypedDict, TypeVar, Generic, Callable, ParamSpec
@runtime_checkable
class SupportsClose(Protocol):
def close(self) -> None: ...
class User(TypedDict):
id: int
name: str
T = TypeVar('T')
P = ParamSpec('P')
def make_cached(fn: Callable[P, T]) -> Callable[P, T]:
cache = {}
def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
key = (args, tuple(sorted(kwargs.items())))
if key not in cache:
cache[key] = fn(*args, **kwargs)
return cache[key]
return wrapper
Guidance & Patterns
- Prefer Protocols over concrete ABCs when only behavior matters.
- Use TypedDict gradually; keep runtime code simple.
Best Practices
- Adopt typing incrementally; enable strictness in CI over time.
- Document public APIs with clear types; avoid over-typing internals.
Exercises
- Define a protocol for a cache and implement two backends; check with mypy/pyright.
- Write a generic function with TypeVar that preserves input type.