Typing and Annotations
Static typing patterns that work well with modern Python type checkers. Results appear in the same fence: same-line # when short, multiline # blocks below the sample when not.
Busca en todas las páginas de la documentación
Static typing patterns that work well with modern Python type checkers. Results appear in the same fence: same-line # when short, multiline # blocks below the sample when not.
Use built-in generics list[str], dict[str, int] (3.9+).
def ids(users: list[dict[str, str]]) -> list[str]:
return [u["id"] for u in users]
ids([{"id": "1"}, {"id": "2"}]) # ['1', '2']Write optional types as T | None (3.10+).
def find(name: str) -> str | None:
return name if name else None
find("Ada") # 'Ada'
find("") # NoneParameterize functions with constrained TypeVars.
from typing import TypeVar
T = TypeVar("T", int, float)
def clamp(x: T, lo: T, hi: T) -> T:
return max(lo, min(x, hi))
clamp(10, 0, 5) # 5
clamp(1.5, 0.0, 1.0) # 1.0Type dict shapes for JSON-like data.
from typing import TypedDict
class UserDict(TypedDict):
id: str
name: str
u: UserDict = {"id": "1", "name": "Ada"}
u["name"] # 'Ada'Import heavy/circular types only for checkers.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from collections.abc import Sequence # not needed at runtime here
TYPE_CHECKING # False at runtimeDescribe function signatures with collections.abc.Callable.
from collections.abc import Callable
Handler = Callable[[str], int]
h: Handler = len
h("hi") # 2Restrict to specific constant values.
from typing import Literal
Mode = Literal["r", "w", "a"]
def open_mode(m: Mode) -> Mode:
return m
open_mode("r") # 'r'Brand primitives to avoid mixing IDs of different domains.
from typing import NewType
UserId = NewType("UserId", str)
uid = UserId("u-1")
str(uid) # 'u-1'Help checkers narrow types after a custom predicate.
from typing import TypeGuard
def is_str_list(x: object) -> TypeGuard[list[str]]:
return isinstance(x, list) and all(isinstance(i, str) for i in x)
is_str_list(["a", "b"]) # True
is_str_list([1, 2]) # FalseGeneric classes with TypeVar parameters.
from typing import Generic, TypeVar
T = TypeVar("T")
class Box(Generic[T]):
def __init__(self, value: T) -> None:
self.value = value
Box(42).value # 42Use cast sparingly when you know more than the checker.
from typing import cast
payload: object = {"id": 1}
user = cast(dict, payload)
user["id"] # 1Express multiple call signatures with @overload.
from typing import overload
@overload
def parse(x: str) -> int: ...
@overload
def parse(x: bytes) -> int: ...
def parse(x: str | bytes) -> int:
return int(x)
parse("10") # 10
parse(b"10") # 10Annotate fluent methods returning the same class with Self (3.11+).
from typing import Self
class Builder:
def __init__(self) -> None:
self.name = ""
def with_name(self, name: str) -> Self:
self.name = name
return self
Builder().with_name("Ada").name # 'Ada'Attach metadata for validators and OpenAPI tools.
from typing import Annotated, get_args, get_origin
UserId = Annotated[str, "path param"]
get_origin(UserId) is Annotated # True
get_args(UserId)[0] is str # TrueMark constants that should not be reassigned.
from typing import Final
MAX_SIZE: Final = 1024
MAX_SIZE # 1024Stack versions: Python 3.14.0 (stable 3.14, maintenance 3.13) · uv 0.6+ · ruff 0.9+
Revisado por Chris St. John·Última actualización: 31 jul 2026